import assert from "node:assert/strict";
import test from "node:test";

import {
  ARUSNAVI_B2_MODEL_PROFILE,
  ARUSNAVI_INTERNAL_SPECIFICATION_REF,
  assertB2ProfileInvariant,
  buildB2HeaderAcknowledgement,
  buildB2PackageAcknowledgement,
  tryParseB2Header2,
  tryParseB2Package,
} from "../src/index.mjs";

const specificationHeader = Buffer.from(
  "FF23E9EF782DE7120300",
  "hex",
);
const specificationPackage = Buffer.from(
  "5B01010000FBDEC251EC5D",
  "hex",
);

test("records the official B2 route, framing and identity evidence", () => {
  assert.equal(assertB2ProfileInvariant(), true);
  assert.equal(ARUSNAVI_B2_MODEL_PROFILE.monitoringServerSlots, 4);
  assert.equal(ARUSNAVI_B2_MODEL_PROFILE.protocol, "INTERNAL");
  assert.equal(ARUSNAVI_B2_MODEL_PROFILE.serverIdentity.kind, "imei");
  assert.equal(
    ARUSNAVI_B2_MODEL_PROFILE.framing.specificationRef,
    ARUSNAVI_INTERNAL_SPECIFICATION_REF,
  );
  assert.equal(
    ARUSNAVI_B2_MODEL_PROFILE.routeCompatibility.gelios,
    "parallel-preserved",
  );
});

test("parses the official HEADER2 example as a claimed IMEI", () => {
  assert.equal(
    tryParseB2Header2(specificationHeader.subarray(0, 9)).status,
    "incomplete",
  );
  const parsed = tryParseB2Header2(specificationHeader);
  assert.equal(parsed.status, "complete");
  assert.equal(parsed.bytesConsumed, 10);
  assert.equal(parsed.identifier.kind, "imei");
  assert.equal(parsed.identifier.value, "865209039777769");
  assert.equal(parsed.identifier.trust, "claimed-not-ownership-proof");
  assert.deepEqual(parsed.evidence, {
    transport: "tcp",
    bytesObserved: 10,
    framingStatus: "verified",
    specificationRef: ARUSNAVI_INTERNAL_SPECIFICATION_REF,
  });
});

test("builds the official HEADER2 acknowledgement example", () => {
  assert.equal(
    buildB2HeaderAcknowledgement(0x52db95de).toString("hex").toUpperCase(),
    "7B0400A0DE95DB527D",
  );
});

test("parses and acknowledges the official package example", () => {
  assert.equal(
    tryParseB2Package(specificationPackage.subarray(0, -1)).status,
    "incomplete",
  );
  assert.deepEqual(tryParseB2Package(specificationPackage), {
    status: "complete",
    bytesConsumed: specificationPackage.length,
    packageNumber: 1,
    packetCount: 1,
  });
  assert.equal(
    buildB2PackageAcknowledgement(1).toString("hex").toUpperCase(),
    "7B00017D",
  );
});

test("uses packet lengths and checksum instead of scanning for 0x5D", () => {
  const packetData = Buffer.from([0x5d]);
  const unixTime = Buffer.from([0x01, 0x00, 0x00, 0x00]);
  const checksum = (0x01 + 0x5d) & 0xff;
  const packageBytes = Buffer.from([
    0x5b,
    0x02,
    0x01,
    packetData.length,
    0x00,
    ...unixTime,
    ...packetData,
    checksum,
    0x5d,
  ]);
  assert.deepEqual(tryParseB2Package(packageBytes), {
    status: "complete",
    bytesConsumed: packageBytes.length,
    packageNumber: 2,
    packetCount: 1,
  });
});

test("fails closed on unsupported headers and malformed packages", () => {
  assert.throws(
    () => tryParseB2Header2(Buffer.from("FE23E9EF782DE7120300", "hex")),
    /b2_header_start_invalid/,
  );
  assert.throws(
    () => tryParseB2Header2(Buffer.from("FF24E9EF782DE7120300", "hex")),
    /b2_header_version_unsupported/,
  );
  const badChecksum = Buffer.from(specificationPackage);
  badChecksum[badChecksum.length - 2] ^= 0xff;
  assert.throws(
    () => tryParseB2Package(badChecksum),
    /b2_packet_checksum_invalid/,
  );
});

test("exports no command builder and keeps transport disabled", () => {
  assert.equal(ARUSNAVI_B2_MODEL_PROFILE.commandTransport.status, "disabled");
  assert.equal(
    ARUSNAVI_B2_MODEL_PROFILE.commandTransport.exportedCommandBuilders,
    0,
  );
});
