import assert from "node:assert/strict";
import { after, before, test } from "node:test";

import { createServer } from "vite";

let server;
let parseDatasetGatewayCatalog;
let parseDatasetNativeScanPreview;
let parseDatasetGroundComparison;
let fetchDatasetGatewayCatalog;
let fetchDatasetNativeScanPreview;
let fetchDatasetGroundComparison;
let DatasetGatewayContractError;

before(async () => {
  server = await createServer({
    appType: "custom",
    logLevel: "silent",
    server: { middlewareMode: true },
  });
  ({
    parseDatasetGatewayCatalog,
    parseDatasetNativeScanPreview,
    parseDatasetGroundComparison,
    fetchDatasetGatewayCatalog,
    fetchDatasetNativeScanPreview,
    fetchDatasetGroundComparison,
    DatasetGatewayContractError,
  } = await server.ssrLoadModule("/src/core/lidar/datasetGateway.ts"));
});

after(async () => {
  await server?.close();
});

function catalog(overrides = {}) {
  return {
    schema_version: "missioncore.dataset-gateway-catalog/v3",
    access: "read-only",
    storage: {
      configured: false,
      required_windows_root: "D:\\NDC_MISSIONCORE\\datasets",
      required_wsl_root: "/mnt/d/NDC_MISSIONCORE/datasets",
      admitted: false,
      status: "blocked-storage-policy",
      attestation: "none",
      manifest_valid: false,
      path_exposed: false,
    },
    sources: [{
      source_id: "goose-3d/v2025-08-22",
      source_kind: "goose",
      display_name: "GOOSE 3D",
      role: "primary-offroad-semantic-baseline",
      license: "CC-BY-SA-4.0",
      commercial_use: "allowed-with-share-alike",
      format: "semantickitti-xyzi-label",
      frame_semantics: "one-lidar-revolution",
      sensor: "VLS-128",
      platforms: ["MuCAR-3", "ALICE", "Spot"],
      annotations: ["semantic-point", "instance-point"],
      superclasses: ["natural-ground", "obstacle"],
      download: {
        automatic: false,
        reason: "operator-admitted-large-artifact-only",
        smoke_example_mb: null,
        primary_scan_archive_gb: 3.3,
        label_archive_gb: null,
        poses_archive_gb: null,
        validation_archive_gb: 3.3,
      },
      statistics: {
        fragment_count: 8,
        annotated_scan_count: 961,
      },
      admission: {
        status: "blocked-storage-policy",
        archive: null,
        frame: null,
      },
    }, {
      source_id: "rellis-3d/v1.1",
      source_kind: "rellis",
      display_name: "RELLIS-3D",
      role: "independent-offroad-cross-dataset-check",
      license: "CC-BY-NC-SA-3.0",
      commercial_use: "research-only-license-review-required",
      format: "semantickitti-xyzi-label",
      frame_semantics: "one-lidar-revolution",
      sensor: "Ouster OS1 64",
      platforms: ["Clearpath Warthog"],
      annotations: ["semantic-point"],
      superclasses: ["ground", "obstacle", "ignore"],
      download: {
        automatic: false,
        reason: "operator-admitted-large-artifact-only",
        smoke_example_mb: 24,
        primary_scan_archive_gb: 14,
        label_archive_gb: 0.174,
        poses_archive_gb: 0.174,
      },
      statistics: {
        fragment_count: 5,
        annotated_scan_count: 13_556,
      },
      admission: {
        status: "blocked-storage-policy",
        archive: null,
        frame: null,
      },
    }],
    representations: [
      {
        id: "native-scan",
        title: "Одиночный исходный скан",
        purpose: "dataset-ground-truth-and-sensor-domain",
        accumulation: false,
      },
      {
        id: "normalized-scan",
        title: "Нормализованный sensor-frame скан",
        purpose: "deskew-filter-inference-and-algorithm-comparison",
        accumulation: false,
      },
      {
        id: "rolling-local-map",
        title: "Накопленная локальная карта",
        purpose: "stable-operator-view-and-local-planning",
        accumulation: true,
      },
    ],
    pipeline: [{
      stage: "deskew",
      requires: ["per-point-time", "imu-or-odometry"],
      produces: "normalized-scan",
    }],
    known_inputs: [{
      source_id: "current-recorded-lidar/vendor-map",
      representation: "vendor-mapped-increment",
      native_scan: false,
      per_point_time: false,
      ring_or_line: false,
      admitted_for_patchworkpp: false,
      reason: "post-lio-map-product-cannot-be-reconstructed-as-a-native-scan",
    }],
    next_action: "configure-dataset-root-on-worker-d",
    ...overrides,
  };
}

test("parses three distinct LiDAR representations and current-input boundary", () => {
  const parsed = parseDatasetGatewayCatalog(catalog());
  assert.deepEqual(
    parsed.representations.map((item) => item.id),
    ["native-scan", "normalized-scan", "rolling-local-map"],
  );
  assert.equal(parsed.representations[2].accumulation, true);
  assert.equal(parsed.currentInput.admittedForPatchworkpp, false);
  assert.equal(parsed.sources[0].frameSemantics, "one-lidar-revolution");
  assert.equal(parsed.sources[1].sourceKind, "rellis");
});

test("rejects path exposure and upgraded K1 semantics", () => {
  const exposed = catalog();
  exposed.storage.path_exposed = true;
  assert.throws(
    () => parseDatasetGatewayCatalog(exposed),
    DatasetGatewayContractError,
  );

  const upgraded = catalog();
  upgraded.known_inputs[0].per_point_time = true;
  assert.throws(
    () => parseDatasetGatewayCatalog(upgraded),
    DatasetGatewayContractError,
  );
});

test("fetches the read-only gateway endpoint", async () => {
  const calls = [];
  const parsed = await fetchDatasetGatewayCatalog({
    fetcher: async (url, init) => {
      calls.push({ url, init });
      return new Response(JSON.stringify(catalog()), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      });
    },
  });
  assert.equal(calls[0].url, "/api/v1/lidar/dataset-gateway");
  assert.equal(calls[0].init.method, "GET");
  assert.equal(parsed.sources[0].displayName, "GOOSE 3D");
});

test("decodes one bounded point-aligned native-scan preview", async () => {
  const payload = {
    schema_version: "missioncore.dataset-native-scan-preview/v1",
    source_id: "goose-3d/v2025-08-22",
    frame_id: "frame-1",
    representation: "native-scan",
    sampling: "deterministic-even-index",
    source_point_count: 2,
    point_count: 2,
    points_xyz_m: [[1, 2, 3], [4, 5, 6]],
    remission_0_to_255: [0, 255],
    semantic_label_ids: [23, 38],
    semantic_rgb_0_to_255: [255, 47, 128, 1, 51, 73],
    ground_truth_ground: [1, 0],
    classes: [
      {
        label_id: 23,
        class_name: "asphalt",
        hex: "#ff2f80",
        challenge_category_id: 2,
        challenge_category_name: "artificial_ground",
      },
    ],
    safety: {
      visualization_only: true,
      navigation_or_safety_accepted: false,
    },
  };
  const parsed = parseDatasetNativeScanPreview(payload);
  assert.equal(parsed.pointCount, 2);
  assert.deepEqual(parsed.groundTruthGround, [1, 0]);

  let requestedUrl = null;
  const fetched = await fetchDatasetNativeScanPreview({
    fetcher: async (url) => {
      requestedUrl = url;
      return new Response(JSON.stringify(payload), { status: 200 });
    },
  });
  assert.equal(fetched.frameId, "frame-1");
  assert.deepEqual(fetched.evaluationMask, [1, 1]);
  assert.equal(
    requestedUrl,
    "/api/v1/lidar/dataset-gateway/preview?source_id=goose-3d%2Fv2025-08-22",
  );

  payload.semantic_rgb_0_to_255.pop();
  assert.throws(
    () => parseDatasetNativeScanPreview(payload),
    DatasetGatewayContractError,
  );
});

test("decodes the RELLIS compatibility smoke with explicit ignore mask", async () => {
  const payload = {
    schema_version: "missioncore.dataset-native-scan-preview/v2",
    source_id: "rellis-3d/v1.1",
    frame_id: "000104",
    representation: "native-scan",
    sampling: "deterministic-even-index",
    source_point_count: 3,
    point_count: 3,
    points_xyz_m: [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
    remission_0_to_255: [0, 127, 255],
    semantic_label_ids: [3, 4, 31],
    semantic_rgb_0_to_255: [0, 102, 0, 0, 255, 0, 239, 255, 134],
    ground_truth_ground: [1, 0, 0],
    evaluation_mask: [1, 1, 0],
    classes: [
      {
        label_id: 3,
        class_name: "grass",
        hex: "#006600",
        ground_target: "ground",
        source_point_count: 1,
      },
      {
        label_id: 4,
        class_name: "tree",
        hex: "#00ff00",
        ground_target: "non-ground",
        source_point_count: 1,
      },
      {
        label_id: 31,
        class_name: "puddle",
        hex: "#efff86",
        ground_target: "ignore",
        source_point_count: 1,
      },
    ],
    coordinate_frame: {
      frame_id: "sensor/lidar/os1",
      handedness: "right",
      x: "forward",
      y: "left",
      z: "up",
      transform_applied: false,
    },
    ground_policy: {
      schema_version: "missioncore.rellis-ground-target-policy/v1",
      ground: ["grass"],
      non_ground: ["tree"],
      ignore: ["puddle"],
    },
    source_evidence: {
      repository_url: "https://github.com/unmannedlab/RELLIS-3D",
      repository_commit: "c17a118fcaed1559f03cc32cc3a91dedc557f8b8",
      label_config_sha256: "5".repeat(64),
      point_sha256: "e".repeat(64),
      label_sha256: "9".repeat(64),
      license: "CC-BY-NC-SA-3.0",
    },
    safety: {
      visualization_only: true,
      compatibility_smoke_only: true,
      navigation_or_safety_accepted: false,
    },
  };
  const parsed = parseDatasetNativeScanPreview(payload);
  assert.equal(parsed.sourceId, "rellis-3d/v1.1");
  assert.deepEqual(parsed.evaluationMask, [1, 1, 0]);
  assert.equal(parsed.classes[2].groundTarget, "ignore");
  assert.equal(parsed.coordinateFrame.frameId, "sensor/lidar/os1");

  let requestedUrl = null;
  await fetchDatasetNativeScanPreview({
    sourceId: "rellis-3d/v1.1",
    fetcher: async (url) => {
      requestedUrl = url;
      return new Response(JSON.stringify(payload), { status: 200 });
    },
  });
  assert.equal(
    requestedUrl,
    "/api/v1/lidar/dataset-gateway/preview?source_id=rellis-3d%2Fv1.1",
  );
});

test("decodes a point-aligned current-vs-Patchwork++ comparison", async () => {
  const payload = {
    schema_version: "missioncore.dataset-ground-comparison-preview/v2",
    source_id: "goose-3d/v2025-08-22",
    frame_id: "frame-1",
    sampling: "deterministic-even-index",
    point_count: 2,
    current_ground: [1, 1],
    patchwork_ground: [1, 0],
    patchwork_assigned: [1, 1],
    ground_truth_ground: [1, 0],
    evaluated: [1, 1],
    current_disagreement: [0, 1],
    patchwork_disagreement: [0, 0],
    metrics: {
      current: {
        true_positive: 1,
        false_positive: 1,
        false_negative: 0,
        true_negative: 0,
        precision: 0.5,
        recall: 1,
        f1: 2 / 3,
        ground_iou: 0.5,
        accuracy: 0.5,
        artificial_ground_recall: 1,
        natural_ground_recall: 0,
        obstacle_non_ground_recall: 1,
      },
      patchworkpp: {
        true_positive: 1,
        false_positive: 0,
        false_negative: 0,
        true_negative: 1,
        precision: 1,
        recall: 1,
        f1: 1,
        ground_iou: 1,
        accuracy: 1,
        artificial_ground_recall: 1,
        natural_ground_recall: 1,
        obstacle_non_ground_recall: 1,
      },
    },
    latency_ms: {
      current: 12.5,
      patchworkpp: 0.4,
    },
    patchwork_assigned_fraction: 1,
    providers: {
      current: {
        provider_id: "missioncore-local-percentile-ground/v1",
        implementation_sha256: "a".repeat(64),
        ground_truth: false,
      },
      patchworkpp: {
        provider_id: "patchworkpp/v1.4.1",
        source_url: "https://github.com/url-kaist/patchwork-plusplus",
        source_tag: "v1.4.1",
        source_commit: "3e6903a1d5537a4cc2ace897b0bbb98a92d6014c",
        binding_version: "0.0.1",
        binary_sha256: "b".repeat(64),
        platform: "linux",
        machine: "x86_64",
        ground_truth: false,
      },
    },
    input_profile: {
      schema_version: "missioncore.goose-patchwork-profile/v1",
      source_id: "goose-3d/v2025-08-22",
      representation: "native-scan",
      sensor_frame: {
        frame_id: "sensor/lidar/vls128_roof",
        handedness: "right",
        x: "forward",
        y: "left",
        z: "up",
        one_revolution: true,
      },
      height: {
        base_link_above_ground_m: 0.64,
        lidar_above_base_link_m: 1.6,
        sensor_above_ground_m: 2.24,
        evidence: "published-dimensioned-schematic",
      },
      scope: {
        patchworkpp_eligible: true,
        normalized_scan_produced: false,
        complete_vehicle_transform_known: false,
        deskew_claimed: false,
      },
    },
    safety: {
      qualification_only: true,
      navigation_or_safety_accepted: false,
    },
  };
  const parsed = parseDatasetGroundComparison(payload);
  assert.equal(parsed.metrics.current.groundIou, 0.5);
  assert.equal(parsed.metrics.patchworkpp.groundIou, 1);
  assert.deepEqual(parsed.patchworkDisagreement, [0, 0]);
  assert.equal(parsed.inputProfile.sensorHeightM, 2.24);

  const fetched = await fetchDatasetGroundComparison({
    fetcher: async () => new Response(JSON.stringify(payload), { status: 200 }),
  });
  assert.equal(fetched.latencyMs.patchworkpp, 0.4);

  payload.patchwork_disagreement.pop();
  assert.throws(
    () => parseDatasetGroundComparison(payload),
    DatasetGatewayContractError,
  );
  payload.patchwork_disagreement.push(0);
  payload.input_profile.height.sensor_above_ground_m = 2.25;
  assert.throws(
    () => parseDatasetGroundComparison(payload),
    DatasetGatewayContractError,
  );
});
