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

import {
  INI_PANEL_ENTRIES,
  createControlPageBrowserApiMethods,
  createIniPanelLaunchApiManifest,
  createIniPanelLaunchApiSchema,
  createIniPanelShellIntegrationManifest,
  createIniPanelShellViewModel,
  getVisibleIniPanelEntries,
  isSupportedIniPanelLaunchApiManifest,
} from "../../../runtime/ui/ini-panel/ui-shell.js";

const __dirname = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dirname, "../../..");
const launchText = readFileSync(resolve(root, "runtime/ui/ini-panel/launch.html"), "utf8");
const shellText = readFileSync(resolve(root, "runtime/ui/ini-panel/ui-shell.js"), "utf8");

const manifest = createIniPanelLaunchApiManifest();
const schema = createIniPanelLaunchApiSchema();

assert.deepEqual(schema, {
  apiName: "ini-panel-launch",
  manifestVersion: 1,
  fields: [
    "apiName",
    "manifestVersion",
    "methods",
    "visibleEntries",
    "targetPages",
    "controlPageApiMethods",
    "persistenceCapabilities",
  ],
});

assert.deepEqual(manifest, {
  apiName: "ini-panel-launch",
  manifestVersion: 1,
  methods: [
    "isSupportedLaunchApiManifest",
    "getLaunchApiSchema",
    "getLaunchApiManifest",
    "getShellIntegrationSchema",
    "getShellIntegrationManifest",
    "getShellIntegrationReadiness",
    "getShellSessionHandoffSummarySchema",
    "getShellSessionHandoffSummary",
    "isSupportedShellSessionHandoffSummary",
    "getShellSessionHandoffCompatibilityReport",
    "getShellSessionHandoffDisplayViewModel",
    "getShellSessionHandoffSnapshot",
    "getShellSessionHandoffRenderState",
    "getShellSessionHandoffActionPlan",
    "getShellSessionHandoffChecklist",
    "getShellSessionHandoffPackageSchema",
    "getShellSessionHandoffPackage",
    "getShellSessionHandoffPackageReport",
    "getShellSessionHandoffPackageDisplayViewModel",
    "getShellSessionHandoffPackageRenderState",
    "getShellSessionHandoffPackageMountState",
    "getShellSessionHandoffPackageMountDisplayViewModel",
    "getShellSessionHandoffPackageMountRenderState",
    "getShellSessionHandoffMountDomContract",
    "getShellSessionHandoffMountDomReadiness",
    "renderShellSessionHandoffMountState",
    "mountShellSessionHandoff",
    "mountShellSessionHandoffFromControlPage",
    "readShellSessionHandoffStatusFromControlPage",
    "getShellSessionHandoffWorkflowSummary",
    "getShellSessionReadinessWorkflowReport",
    "getShellSessionHandoffWorkflowDisplayViewModel",
    "getShellSessionHandoffWorkflowRenderState",
    "getShellSessionHandoffWorkflowDomContract",
    "getShellSessionHandoffWorkflowDomReadiness",
    "renderShellSessionHandoffWorkflowState",
    "mountShellSessionHandoffWorkflow",
    "getWorkflowOverviewContract",
    "getWorkflowOverviewReadiness",
    "mountWorkflowOverviewEmbedding",
    "getWorkflowOverviewEmbeddingReport",
    "getWorkflowOverviewEmbeddingDisplayViewModel",
    "getWorkflowOverviewEmbeddingRenderState",
    "getWorkflowOverviewEmbeddingDomContract",
    "getWorkflowOverviewEmbeddingDomReadiness",
    "renderWorkflowOverviewEmbeddingState",
    "mountWorkflowOverviewEmbeddingState",
    "getWorkflowOverviewEmbeddingMountDisplayViewModel",
    "getWorkflowOverviewEmbeddingMountRenderState",
    "getWorkflowOverviewEmbeddingMountDomContract",
    "getWorkflowOverviewEmbeddingMountDomReadiness",
    "renderWorkflowOverviewEmbeddingMountState",
    "mountWorkflowOverviewEmbeddingMountState",
    "isSupportedShellSessionHandoffPackage",
    "getLauncherLinks",
    "getControlPageApiMethods",
  ],
  visibleEntries: [
    {
      id: "edit-run",
      href: "./index.html",
      title: "Open edit and run panel",
    },
    {
      id: "control-view",
      href: "./control-page.html",
      title: "Open read-only control view",
    },
    {
      id: "workflow-overview",
      href: "./workflow-overview.html",
      title: "Open shell handoff overview",
    },
  ],
  targetPages: [
    {
      entryId: "edit-run",
      href: "./index.html",
    },
    {
      entryId: "control-view",
      href: "./control-page.html",
    },
    {
      entryId: "workflow-overview",
      href: "./workflow-overview.html",
    },
  ],
  controlPageApiMethods: createControlPageBrowserApiMethods(),
  persistenceCapabilities: [
    {
      id: "machine-files",
      label: "Machine text files",
      scope: "opfs",
    },
    {
      id: "session-snapshot",
      label: "Machine session snapshot",
      scope: "opfs",
    },
    {
      id: "readonly-status",
      label: "Read-only machine session status",
      scope: "control-page",
    },
  ],
});

assert.deepEqual(createIniPanelShellViewModel().launchApiManifest, manifest);
assert.deepEqual(createIniPanelShellViewModel().launchApiSchema, schema);
assert.deepEqual(
  createIniPanelShellViewModel().shellIntegrationManifest,
  createIniPanelShellIntegrationManifest(),
);
assert.equal(createIniPanelShellViewModel().launchApiManifest.manifestVersion, schema.manifestVersion);
assert.equal(isSupportedIniPanelLaunchApiManifest(manifest), true);
assert.equal(isSupportedIniPanelLaunchApiManifest({ ...manifest, manifestVersion: 2 }), false);
assert.equal(isSupportedIniPanelLaunchApiManifest({ ...manifest, apiName: "other" }), false);
const missingFieldManifest = { ...manifest };
delete missingFieldManifest.persistenceCapabilities;
assert.equal(isSupportedIniPanelLaunchApiManifest(missingFieldManifest), false);
assert.equal(isSupportedIniPanelLaunchApiManifest(null), false);
assert.deepEqual(getVisibleIniPanelEntries(), INI_PANEL_ENTRIES);

manifest.visibleEntries[0].title = "changed";
manifest.targetPages[0].href = "./changed.html";
manifest.controlPageApiMethods.push("changedMethod");
manifest.persistenceCapabilities[0].label = "changed";
assert.equal(INI_PANEL_ENTRIES[0].title, "Open edit and run panel");
assert.equal(createIniPanelLaunchApiManifest().targetPages[0].href, "./index.html");
assert.deepEqual(createIniPanelLaunchApiManifest().controlPageApiMethods, createControlPageBrowserApiMethods());
assert.equal(createIniPanelLaunchApiManifest().persistenceCapabilities[0].label, "Machine text files");

const customManifest = createIniPanelLaunchApiManifest([
  {
    id: "custom",
    href: "./custom.html",
    title: "Custom entry",
  },
]);
assert.deepEqual(customManifest.visibleEntries, [
  {
    id: "custom",
    href: "./custom.html",
    title: "Custom entry",
  },
]);
assert.deepEqual(customManifest.targetPages, [
  {
    entryId: "custom",
    href: "./custom.html",
  },
]);

assert.match(shellText, /\bexport function createIniPanelLaunchApiManifest\b/);
assert.match(shellText, /\bexport function createIniPanelLaunchApiSchema\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelLaunchApiManifest\b/);
assert.match(launchText, /\bisSupportedLaunchApiManifest\b/);
assert.match(launchText, /\bgetLaunchApiSchema\b/);
assert.match(launchText, /\bgetLaunchApiManifest\b/);
assert.match(launchText, /\bgetShellIntegrationSchema\b/);
assert.match(launchText, /\bgetShellIntegrationManifest\b/);
assert.match(launchText, /\bgetShellIntegrationReadiness\b/);
assert.match(launchText, /\bgetShellSessionHandoffSummarySchema\b/);
assert.match(launchText, /\bgetShellSessionHandoffSummary\b/);
assert.match(launchText, /\bisSupportedShellSessionHandoffSummary\b/);
assert.match(launchText, /\bgetShellSessionHandoffCompatibilityReport\b/);
assert.match(launchText, /\bgetShellSessionHandoffDisplayViewModel\b/);
assert.match(launchText, /\bgetShellSessionHandoffSnapshot\b/);
assert.match(launchText, /\bgetShellSessionHandoffRenderState\b/);
assert.match(launchText, /\bgetShellSessionHandoffActionPlan\b/);
assert.match(launchText, /\bgetShellSessionHandoffChecklist\b/);
assert.match(launchText, /\bgetShellSessionHandoffPackageSchema\b/);
assert.match(launchText, /\bgetShellSessionHandoffPackage\b/);
assert.match(launchText, /\bgetShellSessionHandoffPackageReport\b/);
assert.match(launchText, /\bgetShellSessionHandoffPackageDisplayViewModel\b/);
assert.match(launchText, /\bgetShellSessionHandoffPackageRenderState\b/);
assert.match(launchText, /\bgetShellSessionHandoffPackageMountState\b/);
assert.match(launchText, /\bgetShellSessionHandoffPackageMountDisplayViewModel\b/);
assert.match(launchText, /\bgetShellSessionHandoffPackageMountRenderState\b/);
assert.match(launchText, /\bgetShellSessionHandoffMountDomContract\b/);
assert.match(launchText, /\bgetShellSessionHandoffMountDomReadiness\b/);
assert.match(launchText, /\brenderShellSessionHandoffMountState\b/);
assert.match(launchText, /\bmountShellSessionHandoff\b/);
assert.match(launchText, /\bmountShellSessionHandoffFromControlPage\b/);
assert.match(launchText, /\breadShellSessionHandoffStatusFromControlPage\b/);
assert.match(launchText, /\bgetShellSessionHandoffWorkflowSummary\b/);
assert.match(launchText, /\bgetShellSessionReadinessWorkflowReport\b/);
assert.match(launchText, /\bgetShellSessionHandoffWorkflowDisplayViewModel\b/);
assert.match(launchText, /\bgetShellSessionHandoffWorkflowRenderState\b/);
assert.match(launchText, /\bgetShellSessionHandoffWorkflowDomContract\b/);
assert.match(launchText, /\bgetShellSessionHandoffWorkflowDomReadiness\b/);
assert.match(launchText, /\brenderShellSessionHandoffWorkflowState\b/);
assert.match(launchText, /\bmountShellSessionHandoffWorkflow\b/);
assert.match(launchText, /\bgetWorkflowOverviewContract\b/);
assert.match(launchText, /\bgetWorkflowOverviewReadiness\b/);
assert.match(launchText, /\bmountWorkflowOverviewEmbedding\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingReport\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingDisplayViewModel\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingRenderState\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingDomContract\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingDomReadiness\b/);
assert.match(launchText, /\brenderWorkflowOverviewEmbeddingState\b/);
assert.match(launchText, /\bmountWorkflowOverviewEmbeddingState\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingMountDisplayViewModel\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingMountRenderState\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingMountDomContract\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingMountDomReadiness\b/);
assert.match(launchText, /\brenderWorkflowOverviewEmbeddingMountState\b/);
assert.match(launchText, /\bmountWorkflowOverviewEmbeddingMountState\b/);
assert.match(launchText, /\bisSupportedShellSessionHandoffPackage\b/);
assert.match(launchText, /\bdata-handoff-workflow\b/);
assert.match(launchText, /\bdata-handoff-workflow-status\b/);
assert.match(launchText, /\bdata-handoff-workflow-rows\b/);
assert.match(launchText, /\bdata-handoff-mount\b/);
assert.match(launchText, /\bdata-handoff-mount-status\b/);
assert.match(launchText, /\bdata-handoff-mount-rows\b/);
assert.match(launchText, /\blinuxCncIniPanelLaunchApi\b/);

console.log("ini_panel_launch_api_manifest_node_smoke=ok");
