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

import { createServer } from "vite";

let server;
let decodePolygonRunCatalog;
let decodePolygonRunDetail;
let fetchPolygonRunCatalog;
let fetchPolygonRunDetail;
let resolvePolygonRunRoute;
let PolygonRunContractError;
let decodePolygonWorkerStatus;
let decodePolygonVehicleState;
let decodePolygonCommandAcceptance;
let fetchPolygonWorkerStatus;
let fetchPolygonVehicleState;
let sendPolygonRoverCommand;
let startPolygonWorker;
let stopPolygonWorker;
let PolygonWorkerContractError;
let workspaceById;
let workspacesForRoot;
let roots;

before(async () => {
  server = await createServer({
    appType: "custom",
    logLevel: "silent",
    server: { middlewareMode: true },
  });
  ({
    decodePolygonRunCatalog,
    decodePolygonRunDetail,
    fetchPolygonRunCatalog,
    fetchPolygonRunDetail,
    resolvePolygonRunRoute,
    PolygonRunContractError,
  } = await server.ssrLoadModule("/src/core/polygon/runArchive.ts"));
  ({
    decodePolygonWorkerStatus,
    decodePolygonVehicleState,
    decodePolygonCommandAcceptance,
    fetchPolygonWorkerStatus,
    fetchPolygonVehicleState,
    sendPolygonRoverCommand,
    startPolygonWorker,
    stopPolygonWorker,
    PolygonWorkerContractError,
  } = await server.ssrLoadModule("/src/core/polygon/liveWorker.ts"));
  ({
    workspaceById,
    workspacesForRoot,
    roots,
  } = await server.ssrLoadModule("/src/productModel.ts"));
});

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

function summary(overrides = {}) {
  return {
    run_id: "s1b-6cb1495-20260724t1535z",
    episode_id: "episode-s1b-6cb1495-20260724t1535z",
    kind: "simulation_closed_loop",
    state: "completed",
    created_at_utc: "2026-07-24T15:35:00Z",
    started_at_utc: "2026-07-24T15:35:02Z",
    ended_at_utc: "2026-07-24T15:35:05Z",
    terminal_reason: "operator-stop-clean",
    scenario_generation: "px4-v1.17.0-stock-rover-ackermann",
    profile_generation: "stock-rover-lifecycle-v1",
    mission_core_commit: "6cb1495a1234567890abcdef1234567890abcdef",
    host_profile_id: "mission-gpu-s0",
    reproducibility_tier: "R1",
    clock_domain: "gazebo:/clock",
    revision: 5,
    provider_ids: ["px4-autopilot", "gazebo"],
    artifact_count: 1,
    ...overrides,
  };
}

function catalog(overrides = {}) {
  return {
    schema_version: "missioncore.polygon-run-catalog/v1",
    access: "read-only",
    items: [summary()],
    total: 1,
    limitations: ["Qualification evidence only."],
    ...overrides,
  };
}

function detail(overrides = {}) {
  return {
    schema_version: "missioncore.polygon-run-detail/v1",
    access: "read-only",
    run: {
      ...summary(),
      scenario_sha256: "a".repeat(64),
      profile_sha256: "b".repeat(64),
      host_profile_sha256: "c".repeat(64),
      seed: 42,
      parent_run_id: null,
      providers: [
        {
          identifier: "px4-autopilot",
          version: "v1.17.0",
          revision: "v1.17.0",
          digest: null,
        },
        {
          identifier: "gazebo",
          version: "harmonic",
          revision: "8.9.0",
          digest: null,
        },
      ],
      authority: {
        generation: 1,
        command_ttl_max_ns: 250_000_000,
        heartbeat_timeout_monotonic_ns: 500_000_000,
        simulation_or_shadow_only: true,
        actuator_authority: false,
        navigation_or_safety_accepted: false,
        direct_actuator_setpoints_allowed: false,
      },
    },
    events: [
      {
        schema_version: "missioncore.qualification-event/v1",
        run_id: "s1b-6cb1495-20260724t1535z",
        sequence: 5,
        event_type: "lifecycle.state-changed",
        observed_at_utc: "2026-07-24T15:35:05Z",
        host_monotonic_ns: 5,
        sim_time_ns: 2_000_000,
        payload: {
          from: "stopping",
          to: "completed",
          reason: "operator-stop-clean",
        },
      },
    ],
    events_total: 1,
    events_truncated: false,
    commands: {
      count: 0,
      content_exposed: false,
    },
    artifacts: [
      {
        artifact_id: "provider-log-index",
        kind: "log-index",
        relative_path: "provider-runtime/processes.json",
        sha256: "a".repeat(64),
        byte_length: 512,
        source_of_record: true,
        sequence: 1,
      },
    ],
    limitations: ["Qualification evidence only."],
    ...overrides,
  };
}

function jsonResponse(payload, status = 200) {
  return new Response(JSON.stringify(payload), {
    status,
    headers: { "content-type": "application/json" },
  });
}

function workerStatus(overrides = {}) {
  return {
    schema_version: "missioncore.simulation-worker-status/v2",
    worker_id: "mission-gpu-s1",
    transport: "unix",
    mode: "simulation",
    available: true,
    control_available: true,
    active_run_id: "s1c-6cb1495-20260724t180000z-aabbcc",
    run_state: "running",
    active_provider_ids: ["micro-xrce-dds-agent", "px4-gazebo-stock-rover"],
    provider_profile: {
      schema_version: "missioncore.simulation-provider-profile/v1",
      profile_id: "stock-rover-gazebo-px4-s1d",
      providers: [
        {
          provider_id: "gazebo",
          roles: ["world", "physics", "state", "sensor"],
          capabilities: [
            "clock.simulation",
            "state.vehicle-pose",
            "truth.ground-truth",
            "sensor.virtual",
          ],
        },
        {
          provider_id: "px4-ros2-offboard",
          roles: ["controller"],
          capabilities: ["command.rover-speed-steering/v1"],
        },
        {
          provider_id: "micro-xrce-dds-agent",
          roles: ["transport"],
          capabilities: ["transport.ros2"],
        },
      ],
      clock: {
        provider_id: "gazebo",
        domain: "gazebo:/clock",
        unit: "nanoseconds",
        mode: "simulation",
      },
      control_profiles: ["rover-speed-steering/v1"],
      canonical_frames: {
        world: "map_enu",
        body: "base_link_flu",
      },
    },
    isolation: {
      network: "loopback-only-netns",
      process_identity: "missioncore",
      artifact_policy: "d-only",
    },
    authority: {
      scope: "virtual-only",
      actuator_authority: false,
      direct_actuator_setpoints_allowed: false,
    },
    ...overrides,
  };
}

function vehicleState(overrides = {}) {
  return {
    schema_version: "missioncore.vehicle-state/v1",
    run_id: "s1c-6cb1495-20260724t180000z-aabbcc",
    sequence: 7,
    observed_at_utc: "2026-07-24T18:00:07Z",
    host_monotonic_ns: 123_456_789,
    sim_time_ns: 7_000_000_000,
    frame_id: "map_enu",
    child_frame_id: "base_link_flu",
    pose: {
      position_m: { x: 1.25, y: -0.5, z: 0.18 },
      orientation_xyzw: { x: 0, y: 0, z: 0.1, w: 0.995 },
    },
    source: {
      provider: "gazebo",
      topic: "/world/rover/dynamic_pose/info",
      signal: "ground-truth",
      quality: "diagnostic",
    },
    safety: {
      scope: "virtual-only",
      actuator_authority: false,
      navigation_or_safety_accepted: false,
    },
    ...overrides,
  };
}

function commandAcceptance(overrides = {}) {
  return {
    schema_version: "missioncore.command-acceptance/v2",
    run_id: "s1c-6cb1495-20260724t180000z-aabbcc",
    command_id: "cmd-aabbcc",
    sequence: 1,
    issued_at_sim_ns: 7_000_000_000,
    valid_until_sim_ns: 7_250_000_000,
    speed_mps: 1,
    steering_normalized: -0.55,
    authority_scope: "virtual-only",
    delivery: {
      provider_id: "px4-ros2-offboard",
      control_profile: "rover-speed-steering/v1",
      accepted: true,
      controller_ready: true,
      ttl_expired_count: 0,
      diagnostics: {
        armed: true,
        offboard: true,
      },
    },
    ...overrides,
  };
}

test("Polygon exposes one dataset surface and keeps legacy links compatible", () => {
  assert.deepEqual(resolvePolygonRunRoute("?workspace=polygon-run"), {
    active: true,
    runId: null,
    error: null,
  });
  assert.deepEqual(
    resolvePolygonRunRoute("?workspace=polygon-run&run=s1b-6cb1495-20260724t1535z"),
    {
      active: true,
      runId: "s1b-6cb1495-20260724t1535z",
      error: null,
    },
  );
  assert.deepEqual(resolvePolygonRunRoute("?workspace=polygon-datasets"), {
    active: true,
    runId: null,
    error: null,
  });
  assert.equal(resolvePolygonRunRoute("?workspace=missions").active, false);
  assert.match(
    resolvePolygonRunRoute("?workspace=polygon-run&run=../../etc").error,
    /некорректный/,
  );
  assert.equal(workspaceById("polygon-run"), null);
  assert.equal(
    workspacesForRoot("polygon").some(({ id }) => id === "polygon-run"),
    false,
  );
  assert.equal(workspaceById("polygon-datasets").root, "polygon");
  assert.equal(workspaceById("polygon-datasets").kind, "polygon-datasets");
  assert.deepEqual(
    workspacesForRoot("polygon").map(({ id }) => id),
    ["polygon-datasets"],
  );
  assert.equal(
    workspacesForRoot("system").some(({ id }) => id === "polygon-run"),
    false,
  );
  assert.equal(roots.some(({ id }) => id === "polygon"), true);
});

test("Polygon contracts decode path-free evidence and preserve the safety boundary", () => {
  const decodedCatalog = decodePolygonRunCatalog(catalog());
  const decodedDetail = decodePolygonRunDetail(detail());

  assert.equal(decodedCatalog.items[0].state, "completed");
  assert.equal(decodedDetail.run.authority.actuatorAuthority, false);
  assert.equal(decodedDetail.run.authority.navigationOrSafetyAccepted, false);
  assert.equal(decodedDetail.commandCount, 0);
  assert.equal(decodedDetail.artifacts[0].relativePath, "provider-runtime/processes.json");
  assert.equal("content" in decodedDetail, false);
});

test("Polygon contracts fail closed on command content, paths and unknown fields", () => {
  assert.throws(
    () => decodePolygonRunDetail(detail({
      commands: { count: 1, content_exposed: true },
    })),
    PolygonRunContractError,
  );
  assert.throws(
    () => decodePolygonRunDetail(detail({
      artifacts: [{
        ...detail().artifacts[0],
        relative_path: "/mnt/d/private/processes.json",
      }],
    })),
    PolygonRunContractError,
  );
  assert.throws(
    () => decodePolygonRunCatalog(catalog({ unexpected: true })),
    PolygonRunContractError,
  );
});

test("Polygon fetchers use bounded same-origin GET endpoints", async () => {
  const calls = [];
  const fetcher = async (url, init) => {
    calls.push({ url, init });
    return String(url).includes("event_limit") ? jsonResponse(detail()) : jsonResponse(catalog());
  };

  await fetchPolygonRunCatalog({ limit: 20, fetcher });
  await fetchPolygonRunDetail("s1b-6cb1495-20260724t1535z", {
    eventLimit: 200,
    fetcher,
  });

  assert.deepEqual(calls.map(({ url }) => url), [
    "/api/v1/polygon/runs?limit=20",
    "/api/v1/polygon/runs/s1b-6cb1495-20260724t1535z?event_limit=200",
  ]);
  assert.ok(calls.every(({ init }) => init.method === "GET"));
  assert.ok(calls.every(({ init }) => init.headers.Accept === "application/json"));
});

test("Polygon Live decodes only D-only virtual diagnostic state", () => {
  const status = decodePolygonWorkerStatus(workerStatus());
  const live = decodePolygonVehicleState(vehicleState());
  const command = decodePolygonCommandAcceptance(commandAcceptance());

  assert.equal(status.available, true);
  assert.equal(status.activeRunId, live.runId);
  assert.equal(status.isolation.artifactPolicy, "d-only");
  assert.deepEqual(live.position, { x: 1.25, y: -0.5, z: 0.18 });
  assert.equal(command.controllerReady, true);
  assert.equal(command.deliveryProvider, "px4-ros2-offboard");
  assert.equal(command.steeringNormalized, -0.55);
  assert.throws(
    () => decodePolygonWorkerStatus(workerStatus({
      authority: {
        ...workerStatus().authority,
        actuator_authority: true,
      },
    })),
    PolygonWorkerContractError,
  );
  assert.throws(
    () => decodePolygonVehicleState(vehicleState({
      source: {
        ...vehicleState().source,
        quality: "accepted",
      },
    })),
    PolygonWorkerContractError,
  );
  assert.throws(
    () => decodePolygonCommandAcceptance(commandAcceptance({
      authority_scope: "physical",
    })),
    PolygonWorkerContractError,
  );
});

test("Polygon Live accepts an Unreal provider behind the canonical contract", () => {
  const unrealStatus = workerStatus({
    provider_profile: {
      ...workerStatus().provider_profile,
      profile_id: "unreal-native-rover-v1",
      providers: [
        {
          provider_id: "unreal-native",
          roles: ["world", "physics", "state", "sensor"],
          capabilities: [
            "clock.simulation",
            "state.vehicle-pose",
            "truth.ground-truth",
            "sensor.virtual",
          ],
        },
        {
          provider_id: "unreal-direct-control",
          roles: ["controller"],
          capabilities: ["command.rover-speed-steering/v1"],
        },
      ],
      clock: {
        provider_id: "unreal-native",
        domain: "unreal:fixed-step",
        unit: "nanoseconds",
        mode: "simulation",
      },
    },
  });
  const status = decodePolygonWorkerStatus(unrealStatus);
  const live = decodePolygonVehicleState(vehicleState({
    source: {
      provider: "unreal-native",
      topic: "missioncore/vehicle-state",
      signal: "ground-truth",
      quality: "diagnostic",
    },
  }));
  const command = decodePolygonCommandAcceptance(commandAcceptance({
    delivery: {
      provider_id: "unreal-direct-control",
      control_profile: "rover-speed-steering/v1",
      accepted: true,
      controller_ready: true,
      ttl_expired_count: 0,
      diagnostics: { fixed_step: true },
    },
  }));

  assert.equal(status.providerProfile.clock.domain, "unreal:fixed-step");
  assert.equal(live.sourceProvider, "unreal-native");
  assert.equal(command.deliveryProvider, "unreal-direct-control");
});

test("Polygon Live uses same-origin gateway and idempotent lifecycle requests", async () => {
  const calls = [];
  const stopped = workerStatus({
    active_run_id: null,
    run_state: null,
    active_provider_ids: [],
  });
  const fetcher = async (url, init) => {
    calls.push({ url: String(url), init });
    if (String(url).endsWith("/live")) return jsonResponse(vehicleState());
    if (String(url).endsWith("/commands")) return jsonResponse(commandAcceptance());
    if (String(url).endsWith("/stop")) return jsonResponse(stopped);
    return jsonResponse(workerStatus());
  };

  await fetchPolygonWorkerStatus({ fetcher });
  await fetchPolygonVehicleState({ fetcher });
  await startPolygonWorker({ idempotencyKey: "start-001", fetcher });
  await sendPolygonRoverCommand("s1c-6cb1495-20260724t180000z-aabbcc", {
    speedMps: 1,
    steeringNormalized: -0.55,
    idempotencyKey: "command-001",
    fetcher,
  });
  await stopPolygonWorker("s1c-6cb1495-20260724t180000z-aabbcc", {
    idempotencyKey: "stop-001",
    fetcher,
  });

  assert.deepEqual(calls.map(({ url }) => url), [
    "/api/v1/polygon/worker",
    "/api/v1/polygon/worker/live",
    "/api/v1/polygon/worker/runs",
    "/api/v1/polygon/worker/runs/s1c-6cb1495-20260724t180000z-aabbcc/commands",
    "/api/v1/polygon/worker/runs/s1c-6cb1495-20260724t180000z-aabbcc/stop",
  ]);
  assert.equal(calls[2].init.headers["Idempotency-Key"], "start-001");
  assert.equal(calls[3].init.headers["Idempotency-Key"], "command-001");
  assert.equal(calls[4].init.headers["Idempotency-Key"], "stop-001");
  assert.equal(calls[2].init.body, JSON.stringify({ scenario_id: "stock-rover-ackermann" }));
  assert.equal(calls[3].init.body, JSON.stringify({
    speed_mps: 1,
    steering_normalized: -0.55,
  }));
});
