// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.

/**
 * Check whether byte slices are equal to each other using 8-bit comparisons.
 *
 * @param a First array to check equality
 * @param b Second array to check equality
 * @returns `true` if the arrays are equal, `false` otherwise
 *
 * @private
 */
function equalsNaive(a: Uint8Array, b: Uint8Array): boolean {
  for (let i = 0; i < b.length; i++) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}

/** Check whether byte slices are equal to each other using 32-bit comparisons.
 *
 * @param a First array to check equality.
 * @param b Second array to check equality.
 * @returns `true` if the arrays are equal, `false` otherwise.
 *
 * @private
 */
function equals32Bit(a: Uint8Array, b: Uint8Array): boolean {
  const len = a.length;
  const compactOffset = 3 - ((a.byteOffset + 3) % 4);
  const compactLen = Math.floor((len - compactOffset) / 4);
  const compactA = new Uint32Array(
    a.buffer,
    a.byteOffset + compactOffset,
    compactLen,
  );
  const compactB = new Uint32Array(
    b.buffer,
    b.byteOffset + compactOffset,
    compactLen,
  );
  for (let i = 0; i < compactOffset; i++) {
    if (a[i] !== b[i]) return false;
  }
  for (let i = 0; i < compactA.length; i++) {
    if (compactA[i] !== compactB[i]) return false;
  }
  for (let i = compactOffset + compactLen * 4; i < len; i++) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}

/**
 * Byte length threshold for when to use 32-bit comparisons, based on
 * benchmarks.
 *
 * @see {@link https://github.com/denoland/deno_std/pull/4635}
 */
const THRESHOLD_32_BIT = 160;

/**
 * Check whether byte slices are equal to each other.
 *
 * @param a First array to check equality.
 * @param b Second array to check equality.
 * @returns `true` if the arrays are equal, `false` otherwise.
 *
 * @example Basic usage
 * ```ts
 * import { equals } from "@std/bytes/equals";
 *
 * const a = new Uint8Array([1, 2, 3]);
 * const b = new Uint8Array([1, 2, 3]);
 * const c = new Uint8Array([4, 5, 6]);
 *
 * equals(a, b); // true
 * equals(b, c); // false
 * ```
 */
export function equals(a: Uint8Array, b: Uint8Array): boolean {
  if (a.length !== b.length) {
    return false;
  }
  return a.length >= THRESHOLD_32_BIT &&
      (a.byteOffset % 4) === (b.byteOffset % 4)
    ? equals32Bit(a, b)
    : equalsNaive(a, b);
}

// denoCacheMetadata={"headers":{"content-type":"text/typescript","cf-ray":"a223e6564ecd7db6-LAX","content-length":"2424","accept-ranges":"bytes","age":"36641","date":"Tue, 28 Jul 2026 12:31:14 GMT","cf-cache-status":"HIT","etag":"\"f6141d428f5b16eb4da31c97c3729cdd\"","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=hZy%2BwmYyEjQG9IbjLq%2FqEBxF3AGkNNqgfUQrkdt4aQJ0TbO326bUinE6Po2pclGL6GKd2ZLi5zh2vU%2BC3ySvxB%2B8JjL6fm5zSWjIKsrcnwTR3t7FQzrHOVE%3D\"}]}","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","x-content-type-options":"nosniff","x-jsr-backend":"modules","server":"cloudflare","content-security-policy":"default-src 'none'; script-src 'none'; style-src 'none'; img-src 'none'; font-src 'none'; connect-src 'none'; frame-src 'none'; object-src 'none'; frame-ancestors 'none'; sandbox; form-action 'none';","cross-origin-resource-policy":"cross-origin","x-robots-tag":"noindex","set-cookie":"__cf_bm=KOGpYC4EUf5zbc2eeteKpJV4saWwbCbzZpu34u7VOd0-1785241874.9454856-1.0.1.1-ExChRlEDnyP6rpiARcKy795dm7uzZraCnsjfLmE_prCMeNiPUXMnO8vtXMMSJzdnD72RDdnQIqpaBjXP_d1rZPQx9sTnR66hQkyVabiFDhiEOZ6PlViIqOFSLvvoEfho; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:14 GMT","alt-svc":"h3=\":443\"; ma=86400","access-control-allow-origin":"*","cache-control":"public, max-age=31536000, immutable","access-control-expose-headers":"*","vary":"Origin"},"url":"https://jsr.io/@std/bytes/0.224.0/equals.ts","time":1785241874}