import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import type { ProviderAppsConfig } from "./config";

export interface ProviderRelease {
  readonly manifest: Record<string, unknown>;
  readonly manifestBytes: Uint8Array;
  readonly providerBytes: Uint8Array;
  readonly installIndex: string;
  readonly installStyle: Uint8Array;
  readonly installScript: Uint8Array;
  readonly installPowerShell: string;
  readonly startCmd: string;
  readonly installBootstrap: string;
  readonly installLinux: string;
  readonly favicon: Uint8Array;
  readonly panelImage: Uint8Array;
}

export function readProviderRelease(repositoryRoot: string, config: ProviderAppsConfig): ProviderRelease {
  const releaseRoot = resolve(repositoryRoot, config.release.root);
  const manifestBytes = readFileSync(resolve(releaseRoot, config.release.manifestPath));
  const providerBytes = readFileSync(resolve(releaseRoot, config.release.providerPath));
  const manifest = JSON.parse(manifestBytes.toString("utf8")) as Record<string, unknown>;
  const digest = new Bun.CryptoHasher("sha256").update(providerBytes).digest("hex");
  if (manifest.bytes !== providerBytes.byteLength || manifest.sha256 !== digest) {
    throw new Error("Provider release manifest does not match the Python artifact");
  }
  const installRoot = resolve(repositoryRoot, config.install.root);
  const installIndex = readFileSync(resolve(installRoot, config.install.indexPath), "utf8");
  const installStyle = readFileSync(resolve(installRoot, config.install.stylePath));
  const installScript = readFileSync(resolve(installRoot, config.install.scriptPath));
  const startCmdTemplate = readFileSync(resolve(installRoot, config.install.startCmdPath), "utf8");
  const installBootstrapTemplate = readFileSync(resolve(installRoot, config.install.bootstrapPath), "utf8");
  const installLinuxTemplate = readFileSync(resolve(installRoot, config.install.linuxInstallerPath), "utf8");
  const favicon = readFileSync(resolve(installRoot, config.install.faviconPath));
  const panelImage = readFileSync(resolve(installRoot, config.install.panelImagePath));
  const manifestUrl = `${config.publicExposure.publicBaseUrl}${config.release.routes.manifest}`;
  const providerUrl = `${config.publicExposure.publicBaseUrl}${config.release.routes.provider}`;
  const bootstrapUrl = `${config.publicExposure.publicBaseUrl}${config.install.routes.bootstrap}`;
  const runtime = config.install.runtime;
  const renderMap: Record<string, string> = {
    "__MANIFEST_URL__": manifestUrl,
    "__PROVIDER_URL__": providerUrl,
    "__BOOTSTRAP_URL__": bootstrapUrl,
    "__RUNTIME_ROOT__": config.install.runtime.root,
    "__CONNECT_TIMEOUT_SECONDS__": String(runtime.connectTimeoutSeconds),
    "__PROGRESS_INTERVAL_SECONDS__": String(runtime.progressIntervalSeconds),
    "__WIN7_VERSION__": runtime.windows7.version,
    "__WIN7_MINIMUM_VERSION__": runtime.windows7.minimumVersion,
    "__WIN7_DIRECTORY__": runtime.windows7.directory,
    "__WIN7_FILE_NAME__": runtime.windows7.fileName,
    "__WIN7_BYTES__": String(runtime.windows7.bytes),
    "__WIN7_SHA256__": runtime.windows7.sha256,
    "__WIN7_SOURCES__": JSON.stringify(runtime.windows7.sources),
    "__WIN7_SOURCES_PS__": runtime.windows7.sources
      .map((source) => `@{ id='${source.id}'; url='${source.url}'; pipIndexUrl='${source.pipIndexUrl}' }`)
      .join(", "),
    "__MODERN_VERSION__": runtime.windowsModern.version,
    "__MODERN_MINIMUM_VERSION__": runtime.windowsModern.minimumVersion,
    "__MODERN_DIRECTORY__": runtime.windowsModern.directory,
    "__MODERN_FILE_NAME__": runtime.windowsModern.fileName,
    "__MODERN_BYTES__": String(runtime.windowsModern.bytes),
    "__MODERN_SHA256__": runtime.windowsModern.sha256,
    "__MODERN_SOURCES__": JSON.stringify(runtime.windowsModern.sources),
    "__MODERN_SOURCES_PS__": runtime.windowsModern.sources
      .map((source) => `@{ id='${source.id}'; url='${source.url}'; pipIndexUrl='${source.pipIndexUrl}' }`)
      .join(", "),
    "__MINIMUM_PYTHON_VERSION__": config.install.linux.minimumPythonVersion,
    "__PRIVATE_RUNTIME_DIRECTORY__": config.install.linux.privateRuntimeDirectory,
    "__SYSTEMD_RESTART_SECONDS__": String(config.install.linux.systemdRestartSeconds),
    "__PIP_SOURCES_SH__": config.install.linux.pipSources
      .map((source) => `'${source.indexUrl.replaceAll("'", "'\\''")}'`)
      .join(" "),
  };
  const renderTemplate = (template: string): string =>
    Object.entries(renderMap).reduce((value, [placeholder, replacement]) => value.replaceAll(placeholder, replacement), template);
  const installPowerShell = readFileSync(resolve(installRoot, config.install.installerPath), "utf8")
    .replaceAll("__MANIFEST_URL__", manifestUrl)
    .replaceAll("__PROVIDER_URL__", providerUrl)
    .replaceAll("__DEFAULT_SERVER__", config.install.defaults.server)
    .replaceAll("__DEFAULT_CREDENTIAL_FILE__", config.install.defaults.credentialFile)
    .replaceAll("__DEFAULT_AUTOSTART__", String(config.install.defaults.autoStart));
  const startCmd = renderTemplate(startCmdTemplate);
  const installBootstrap = renderTemplate(installBootstrapTemplate);
  const installLinux = renderTemplate(installLinuxTemplate);
  if ([installPowerShell, startCmd, installBootstrap, installLinux].some((value) => /__[A-Z_]+__/u.test(value))) {
    throw new Error("Provider installer contains unresolved release placeholders");
  }
  return {
    manifest,
    manifestBytes,
    providerBytes,
    installIndex,
    installStyle,
    installScript,
    installPowerShell,
    startCmd,
    installBootstrap,
    installLinux,
    favicon,
    panelImage,
  };
}

function allowedInstallOrigin(_origin: string | undefined, config: ProviderAppsConfig): string {
  return config.publicExposure.publicBaseUrl;
}

function installContract(config: ProviderAppsConfig, release: ProviderRelease, origin: string): Record<string, unknown> {
  const installerUrl = `${origin}${config.install.routes.installer}`;
  const startCmdUrl = `${origin}${config.install.routes.startCmd}`;
  const startCmdCommand =
    `certutil -urlcache -f ${startCmdUrl} "%TEMP%\\u.cmd"&&call "%TEMP%\\u.cmd"`;
  const linuxInstallerUrl = `${origin}${config.install.routes.linuxInstaller}`;
  const linuxCommand = `curl -fsSL ${linuxInstallerUrl} | bash`;
  const commonRuntimeBehavior = {
    auto: "reuse a suitable system Python, then a private Python, otherwise install private",
    system: "reuse a suitable system Python or fail with a hint to select private",
    private: "reuse or install Provider-private Python without scanning system Python",
  };
  return {
    schemaVersion: 4,
    product: "unideskcprovider",
    platformsSupported: ["windows", "linux"],
    latestVersion: release.manifest.latestVersion,
    humanUrl: `${origin}${config.install.routes.index}`,
    credential: {
      acquisition: "Request the Provider token from the UniDesk server administrator through a controlled secret channel.",
      serverKey: "PROVIDER_TOKEN",
      paths: {
        windows: `%USERPROFILE%\\.unidesk\\${config.install.defaults.credentialFile}`,
        linux: `~/.unidesk/${config.install.defaults.credentialFile}`,
      },
      format: "utf8-raw-token",
      contents: "one non-empty token with surrounding whitespace removed",
      redactedExample: "a1b2c3...<redacted>...9x8y7z",
      forbiddenFormats: ["json", "quoted-string", "PROVIDER_TOKEN=<token>", "codex-auth-json"],
      codexAuthJson: {
        path: "~/.codex/auth.json",
        relationship: "not-used-by-provider",
        redactedExample: { OPENAI_API_KEY: "sk-...<redacted>" },
      },
    },
    sensitiveInputs: {
      acceptedByWeb: false,
      acceptedByCommandLine: false,
      rule: "Place the Provider token in the credential file through a controlled secret channel before installation.",
    },
    config: {
      paths: { windows: "%USERPROFILE%\\.unidesk\\provider.yaml", linux: "~/.unidesk/provider.yaml" },
      required: ["id", "server", "credentialFile"],
      defaults: config.install.defaults,
      pythonRuntime: {
        field: "pythonRuntime",
        allowed: ["auto", "system", "private"],
        behavior: commonRuntimeBehavior,
      },
      sourceOfTruth: true,
      mustExistBeforeInstall: true,
    },
    installer: { acceptsArguments: false, readsConfigOnly: true },
    platforms: {
      windows: {
        configPath: "%USERPROFILE%\\.unidesk\\provider.yaml",
        credentialPath: `%USERPROFILE%\\.unidesk\\${config.install.defaults.credentialFile}`,
        prerequisites: { powershell: ">=5.1", python: "private Python 3.8 on Windows 7 or 3.11 on Windows 10/11, with tkinter" },
        launchers: {
          powershell: { command: `irm '${installerUrl}' | iex`, support: "Windows 10/11 with PowerShell 5.1+", downloadUrl: null },
          cmd: { command: startCmdCommand, support: "Same command on Windows 7/10/11; explicit runtime modes never fall back", downloadUrl: startCmdUrl, recommended: true },
        },
        oneLineTemplate: startCmdCommand,
      },
      linux: {
        configPath: "~/.unidesk/provider.yaml",
        credentialPath: `~/.unidesk/${config.install.defaults.credentialFile}`,
        prerequisites: { shell: "bash", downloader: "curl", init: "systemd", privilege: "sudo", python: `Python ${config.install.linux.minimumPythonVersion}+` },
        launchers: {
          bash: { command: linuxCommand, support: "systemd Linux host; zero arguments; no Docker or Node", downloadUrl: linuxInstallerUrl, recommended: true },
        },
        oneLineTemplate: linuxCommand,
        service: "unideskcprovider.service",
      },
    },
    endpoints: {
      manifest: `${config.publicExposure.publicBaseUrl}${config.release.routes.manifest}`,
      provider: `${config.publicExposure.publicBaseUrl}${config.release.routes.provider}`,
      bootstrap: `${config.publicExposure.publicBaseUrl}${config.install.routes.bootstrap}`,
      linuxInstaller: linuxInstallerUrl,
      runtimes: {
        windows7: config.install.runtime.windows7,
        windowsModern: config.install.runtime.windowsModern,
      },
    },
    oneLineTemplates: { windows: startCmdCommand, linux: linuxCommand },
    workflow: [
      "Select platforms.windows or platforms.linux.",
      "Write provider.yaml and the raw Provider token to that platform's fixed user path.",
      "Run the selected recommended launcher; it accepts no configuration arguments.",
    ],
    successChecks: [
      "JSON output has ok=true and operation=unideskcprovider.install",
      "provider.yaml contains only the selected non-sensitive settings",
      "the platform autostart authority is enabled when autoStart=true",
      "trans <providerId> argv hostname succeeds and the TCP pool returns ready=desired",
    ],
  };
}

export function releaseResponse(
  method: string,
  pathname: string,
  config: ProviderAppsConfig,
  release: ProviderRelease,
  origin?: string,
): Response {
  if (method !== "GET" && method !== "HEAD") return Response.json({ ok: false, error: "method not allowed" }, { status: 405 });
  if (pathname === config.release.routes.health) {
    return Response.json({
      ok: true,
      service: "provider-apps",
      target: config.target.id,
      latestVersion: release.manifest.latestVersion,
      artifactBytes: release.providerBytes.byteLength,
      artifactSha256: release.manifest.sha256,
    });
  }
  const headers = { "cache-control": "no-cache, no-store, must-revalidate" };
  if (pathname === config.release.routes.manifest) {
    return new Response(method === "HEAD" ? null : release.manifestBytes, {
      headers: { ...headers, "content-type": "application/json; charset=utf-8" },
    });
  }
  if (pathname === config.release.routes.provider) {
    return new Response(method === "HEAD" ? null : release.providerBytes, {
      headers: {
        ...headers,
        "content-type": "text/x-python; charset=utf-8",
        "content-disposition": 'attachment; filename="unideskcprovider.py"',
      },
    });
  }
  const installOrigin = allowedInstallOrigin(origin, config);
  if (pathname === config.install.routes.contract) {
    return Response.json(installContract(config, release, installOrigin), { headers });
  }
  if (pathname === config.install.routes.installer) {
    return new Response(method === "HEAD" ? null : release.installPowerShell, {
      headers: { ...headers, "content-type": "text/plain; charset=utf-8" },
    });
  }
  if (pathname === config.install.routes.startCmd) {
    return new Response(method === "HEAD" ? null : release.startCmd, {
      headers: {
        ...headers,
        "content-type": "application/x-msdos-program; charset=utf-8",
        "content-disposition": 'attachment; filename="unideskcprovider-start.cmd"',
      },
    });
  }
  if (pathname === config.install.routes.bootstrap) {
    return new Response(method === "HEAD" ? null : release.installBootstrap, {
      headers: {
        ...headers,
        "content-type": "text/x-python; charset=utf-8",
        "content-disposition": 'attachment; filename="install-bootstrap.py"',
      },
    });
  }
  if (pathname === config.install.routes.linuxInstaller) {
    return new Response(method === "HEAD" ? null : release.installLinux, {
      headers: {
        ...headers,
        "content-type": "text/x-shellscript; charset=utf-8",
        "content-disposition": 'attachment; filename="install-linux.sh"',
      },
    });
  }
  if (pathname === config.install.routes.index) {
    const index = release.installIndex
      .replaceAll("__LATEST_VERSION__", String(release.manifest.latestVersion))
      .replaceAll("__DEFAULT_SERVER__", config.install.defaults.server)
      .replaceAll("__DEFAULT_CREDENTIAL_FILE__", config.install.defaults.credentialFile)
      .replaceAll(
        "__PYTHON_RUNTIME_AUTO_SELECTED__",
        config.install.defaults.pythonRuntime === "auto" ? "selected" : "",
      )
      .replaceAll(
        "__PYTHON_RUNTIME_SYSTEM_SELECTED__",
        config.install.defaults.pythonRuntime === "system" ? "selected" : "",
      )
      .replaceAll(
        "__PYTHON_RUNTIME_PRIVATE_SELECTED__",
        config.install.defaults.pythonRuntime === "private" ? "selected" : "",
      )
      .replaceAll("__CONTRACT_PATH__", config.install.routes.contract)
      .replaceAll("__FAVICON_PATH__", config.install.routes.favicon)
      .replaceAll("__PANEL_IMAGE_PATH__", config.install.routes.panelImage);
    return new Response(method === "HEAD" ? null : index, {
      headers: {
        ...headers,
        "content-type": "text/html; charset=utf-8",
        "content-security-policy": "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self'; base-uri 'none'; frame-ancestors 'none'",
      },
    });
  }
  if (pathname === config.install.routes.style) {
    return new Response(method === "HEAD" ? null : release.installStyle, {
      headers: { ...headers, "content-type": "text/css; charset=utf-8" },
    });
  }
  if (pathname === config.install.routes.script) {
    return new Response(method === "HEAD" ? null : release.installScript, {
      headers: { ...headers, "content-type": "text/javascript; charset=utf-8" },
    });
  }
  if (pathname === config.install.routes.favicon) {
    return new Response(method === "HEAD" ? null : release.favicon, {
      headers: { ...headers, "content-type": "image/svg+xml; charset=utf-8" },
    });
  }
  if (pathname === config.install.routes.panelImage) {
    return new Response(method === "HEAD" ? null : release.panelImage, {
      headers: { ...headers, "content-type": "image/png" },
    });
  }
  return Response.json({ ok: false, error: "not found", path: pathname }, { status: 404 });
}
