import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";

import {
  analyzeIniRuntimeBoundaries,
  createIniPanelLaunchApiManifest,
  createIniPanelShellSessionReadinessWorkflowReport,
  createIniPanelShellViewModel,
  createIniPanelShellWorkflowOverviewEmbeddingMountDomContract,
  createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness,
  createLinuxCncIniSdk,
  createLinuxCncInterpSdk,
  createMachineSessionSnapshotPayload,
  createSessionSnapshot,
  defaultMachinePaths,
  gcodeFilenameFromProgramPath,
  gcodeProgramPath,
  getOpfsRoot,
  isSupportedIniPanelLaunchApiManifest,
  loadMachineSessionFromOpfs,
  loadMachineSessionSnapshot,
  loadMachineTextFiles,
  loadMachineToolTableFromOpfs,
  loadTextFile,
  machineFilePaths,
  machineIniPath,
  mountIniPanelShellWorkflowOverviewEmbeddingMountState,
  normalizeOpfsPath,
  parameterFilePath,
  planIniFileContextStaging,
  planSimConfigStaging,
  readMachineSessionReadiness,
  renderIniPanelShellWorkflowOverviewEmbeddingMountState,
  restoreMachineParametersFromOpfs,
  saveMachineSessionSnapshot,
  saveMachineTextFiles,
  saveSessionSnapshot,
  saveTextFile,
  sessionSnapshotPath,
  toolTablePath,
  validateSessionSnapshot,
} from "../../../runtime/sdk/src/index.js";

const __dirname = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dirname, "../../..");
const sdkIndexText = readFileSync(resolve(root, "runtime/sdk/src/index.js"), "utf8");
const sdkReadmeText = readFileSync(resolve(root, "runtime/sdk/README.md"), "utf8");
const trackerText = readFileSync(resolve(root, "../PROJECT_COMPLETION_TRACKER.md"), "utf8");

const requiredExports = [
  ["createLinuxCncIniSdk", createLinuxCncIniSdk],
  ["createLinuxCncInterpSdk", createLinuxCncInterpSdk],
  ["planIniFileContextStaging", planIniFileContextStaging],
  ["planSimConfigStaging", planSimConfigStaging],
  ["analyzeIniRuntimeBoundaries", analyzeIniRuntimeBoundaries],
  ["getOpfsRoot", getOpfsRoot],
  ["saveTextFile", saveTextFile],
  ["loadTextFile", loadTextFile],
  ["machineIniPath", machineIniPath],
  ["toolTablePath", toolTablePath],
  ["parameterFilePath", parameterFilePath],
  ["gcodeProgramPath", gcodeProgramPath],
  ["sessionSnapshotPath", sessionSnapshotPath],
  ["defaultMachinePaths", defaultMachinePaths],
  ["normalizeOpfsPath", normalizeOpfsPath],
  ["createMachineSessionSnapshotPayload", createMachineSessionSnapshotPayload],
  ["createSessionSnapshot", createSessionSnapshot],
  ["saveSessionSnapshot", saveSessionSnapshot],
  ["saveMachineSessionSnapshot", saveMachineSessionSnapshot],
  ["loadMachineSessionSnapshot", loadMachineSessionSnapshot],
  ["validateSessionSnapshot", validateSessionSnapshot],
  ["machineFilePaths", machineFilePaths],
  ["saveMachineTextFiles", saveMachineTextFiles],
  ["loadMachineTextFiles", loadMachineTextFiles],
  ["gcodeFilenameFromProgramPath", gcodeFilenameFromProgramPath],
  ["restoreMachineParametersFromOpfs", restoreMachineParametersFromOpfs],
  ["loadMachineToolTableFromOpfs", loadMachineToolTableFromOpfs],
  ["loadMachineSessionFromOpfs", loadMachineSessionFromOpfs],
  ["readMachineSessionReadiness", readMachineSessionReadiness],
  ["createIniPanelLaunchApiManifest", createIniPanelLaunchApiManifest],
  ["isSupportedIniPanelLaunchApiManifest", isSupportedIniPanelLaunchApiManifest],
  ["createIniPanelShellViewModel", createIniPanelShellViewModel],
  ["createIniPanelShellSessionReadinessWorkflowReport", createIniPanelShellSessionReadinessWorkflowReport],
  [
    "createIniPanelShellWorkflowOverviewEmbeddingMountDomContract",
    createIniPanelShellWorkflowOverviewEmbeddingMountDomContract,
  ],
  [
    "createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness",
    createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness,
  ],
  [
    "renderIniPanelShellWorkflowOverviewEmbeddingMountState",
    renderIniPanelShellWorkflowOverviewEmbeddingMountState,
  ],
  [
    "mountIniPanelShellWorkflowOverviewEmbeddingMountState",
    mountIniPanelShellWorkflowOverviewEmbeddingMountState,
  ],
];

for (const [name, value] of requiredExports) {
  assert.equal(typeof value, "function", `${name} SDK export drift`);
  assert.match(sdkIndexText, new RegExp(`\\b${name}\\b`));
  assert.match(sdkReadmeText, new RegExp(`\\b${name}\\b`));
}

assert.equal(machineIniPath("sdk-mill"), "linuxcnc/machines/sdk-mill/machine.ini");
assert.deepEqual(defaultMachinePaths("sdk-mill"), machineFilePaths("sdk-mill"));
assert.equal(gcodeProgramPath("demo.ngc"), "linuxcnc/gcode/demo.ngc");
assert.equal(sessionSnapshotPath("sdk-session"), "linuxcnc/sessions/sdk-session/snapshot.json");
assert.equal(normalizeOpfsPath("linuxcnc/machines/sdk-mill/tool.tbl"), "linuxcnc/machines/sdk-mill/tool.tbl");
assert.equal(gcodeFilenameFromProgramPath("linuxcnc/gcode/demo.ngc"), "demo.ngc");

const launchManifest = createIniPanelLaunchApiManifest();
assert.equal(isSupportedIniPanelLaunchApiManifest(launchManifest), true);
assert.equal(
  launchManifest.methods.includes("mountWorkflowOverviewEmbeddingMountState"),
  true,
);

const shellViewModel = createIniPanelShellViewModel();
assert.equal(
  shellViewModel.launchApiManifest.methods.includes("mountWorkflowOverviewEmbeddingMountState"),
  true,
);
assert.equal(
  shellViewModel.launchApiManifest.methods.includes("getShellSessionReadinessWorkflowReport"),
  true,
);
assert.equal(
  createIniPanelShellSessionReadinessWorkflowReport().apiName,
  "ini-panel-shell-session-readiness-workflow-report",
);
assert.equal(
  shellViewModel.mountWorkflowOverviewEmbeddingMountState,
  mountIniPanelShellWorkflowOverviewEmbeddingMountState,
);

const blockedMount = mountIniPanelShellWorkflowOverviewEmbeddingMountState({ documentRef: null });
assert.equal(blockedMount.apiName, "ini-panel-shell-workflow-overview-embedding-mount-dom-mount");
assert.equal(blockedMount.ready, false);
assert.deepEqual(blockedMount.domReadiness.missing, ["document", "mount", "status", "rows"]);

assert.match(sdkReadmeText, /OPFS\/session persistence/);
assert.match(sdkReadmeText, /INI panel shell handoff/);
assert.match(sdkReadmeText, /workflow overview embedding/);
assert.match(trackerText, /SDK\/API surface/);

console.log("sdk_surface_node_smoke=ok");
