import { createHash } from "node:crypto";

export const ARUSNAVI_B2_MODEL_PROFILE = deepFreeze({
  schemaVersion: "nodedc.device-model-profile.v1",
  profileRef: "arusnavi.b2.internal.v1",
  vendor: "ARUSNAVI",
  model: "B2",
  deviceType: "tracker",
  protocol: "INTERNAL",
  monitoringServerSlots: 4,
  serverIdentity: {
    kind: "imei",
    source: "modem",
    trust: "claimed-not-ownership-proof",
  },
  bootstrap: {
    operatorSurface: "ARUSNAVI_WEB_OR_LOCAL_CONFIGURATOR",
    platformCredentialRequired: false,
    preserveExistingRoutes: true,
  },
  framing: {
    status: "blocked_pending_official_specification",
    maxInitialBytes: 4096,
  },
  commandTransport: {
    status: "disabled",
    exportedCommandBuilders: 0,
  },
  routeCompatibility: {
    gelios: "parallel-preserved",
    automaticCommandFailover: false,
  },
});

export function inspectUnverifiedInitialBytes(input) {
  if (!Buffer.isBuffer(input)) {
    throw new TypeError("b2_initial_bytes_buffer_required");
  }
  if (input.length === 0) {
    throw new TypeError("b2_initial_bytes_empty");
  }
  if (input.length > ARUSNAVI_B2_MODEL_PROFILE.framing.maxInitialBytes) {
    throw new TypeError("b2_initial_bytes_limit_exceeded");
  }

  return Object.freeze({
    schemaVersion: "nodedc.device.protocol-evidence.v1",
    profileRef: ARUSNAVI_B2_MODEL_PROFILE.profileRef,
    status: "official_framing_required",
    bytesObserved: input.length,
    contentDigest: `sha256:${createHash("sha256").update(input).digest("hex")}`,
    identifierExtracted: false,
    commandTransport: "disabled",
  });
}

export function assertB2ProfileInvariant(profile = ARUSNAVI_B2_MODEL_PROFILE) {
  if (profile.monitoringServerSlots !== 4) {
    throw new TypeError("b2_server_slot_count_invalid");
  }
  if (profile.protocol !== "INTERNAL") {
    throw new TypeError("b2_protocol_invalid");
  }
  if (profile.serverIdentity.kind !== "imei") {
    throw new TypeError("b2_identity_kind_invalid");
  }
  if (profile.commandTransport.status !== "disabled") {
    throw new TypeError("b2_command_transport_must_be_disabled");
  }
  if (profile.routeCompatibility.gelios !== "parallel-preserved") {
    throw new TypeError("b2_gelios_route_must_be_preserved");
  }
  return true;
}

function deepFreeze(value) {
  if (!value || typeof value !== "object" || Object.isFrozen(value)) {
    return value;
  }
  Object.values(value).forEach(deepFreeze);
  return Object.freeze(value);
}
