import { spawnSync } from "node:child_process";
import { existsSync } from "node:fs";
import { systemDefaultWorkflowAssetPaths } from "./system-default-workflows-manifest.mjs";

const requiredSystemPromptNames = [
  "worker-common",
  "workflow-common",
  "workflow-planning",
  "pull-request-review-necessity",
  "workflow-execution",
  "issue-create",
  "workflow-create",
  "event-hook-create",
  "followup-recommendation-guidance",
  "human-handoff",
  "merge-guidance",
];

const requiredDistFiles = [
  "dist/cli/main.js",
  "dist/commands/doctor.js",
  "dist/core/eject-packaged-assets.js",
  "dist/git/author-resolution.js",
  "dist/i18n/catalog.js",
  "dist/commands/eject.js",
  "dist/platform/gitea/auth.js",
  "dist/skills/catalog.js",
  ...(process.env.ALPACA_SKIP_SYSTEM_DEFAULT_WORKFLOW_ASSET_CHECK === "1"
    ? []
    : systemDefaultWorkflowAssetPaths),
  "package-assets/system/workflows/mcp-resolution.md",
  "package-assets/system/workflows/skill-resolution.md",
  "package-assets/system/workflows/workflow-maintenance.md",
  "package-assets/system/catalog/skill.json",
  "package-assets/system/catalog/mcp.json",
  "package-assets/system/catalog/metadata.json",
  ...requiredSystemPromptNames.map(
    (name) => `package-assets/system/system-prompts/${name}.md`,
  ),
  "dist/worker/runtime.js",
];

if (!hasTypeScript() && !hasCompleteDist()) {
  run("npm", [
    "install",
    "--include=dev",
    "--ignore-scripts",
    "--no-audit",
    "--no-fund",
    "--global=false",
    "--prefix",
    ".",
    "--no-package-lock",
  ]);
}

if (hasTypeScript()) {
  run(process.execPath, ["scripts/build.mjs"]);
} else if (!hasCompleteDist()) {
  console.error("AlpacaLoop dist files are missing and TypeScript is unavailable.");
  process.exit(1);
}

function hasTypeScript() {
  return existsSync("node_modules/typescript/bin/tsc");
}

function hasCompleteDist() {
  return requiredDistFiles.every((filePath) => existsSync(filePath));
}

function run(command, args) {
  const result = spawnSync(command, args, { stdio: "inherit" });
  const exitCode = result.status ?? 1;
  if (exitCode !== 0) {
    process.exit(exitCode);
  }
}
