#!/usr/bin/env node
/**
 * One-shot starter-pack installer for the madarX printing-press integration.
 *
 * Run via `npm run printing-press:install` (from the repo root).
 *
 * Idempotent: re-running installs deps only if node_modules is missing, then
 * always invokes the starter-pack output into workspace/skills/printing-press/.
 *
 * Does NOT touch the SQLite registry — individual CLIs register themselves
 * via install-cli.mjs after generation.
 */

import { spawnSync } from 'node:child_process';
import path from 'node:path';
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';

const HERE = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(HERE, '..', '..');
const SUB_NODE_MODULES = path.join(HERE, 'node_modules');
const SKILLS_OUT = path.join(ROOT, 'workspace', 'skills', 'printing-press');

function log(msg) {
  console.log(`[printing-press:install] ${msg}`);
}

function fail(msg, code = 1) {
  console.error(`[printing-press:install] ${msg}`);
  process.exit(code);
}

function augmentedPath() {
  // Upstream verifies Go-installed binaries on PATH after `go install`. macOS
  // shells frequently lack $HOME/go/bin until the operator edits .zshrc. Prepend
  // common Go bin locations so the child sees what it just installed.
  const candidates = [
    process.env.GOBIN,
    process.env.GOPATH ? `${process.env.GOPATH}/bin` : null,
    process.env.HOME ? `${process.env.HOME}/go/bin` : null,
  ].filter(Boolean);
  return [...candidates, process.env.PATH || ''].join(':');
}

function run(cmd, args, opts = {}) {
  const env = { ...process.env, PATH: augmentedPath(), ...(opts.env || {}) };
  const result = spawnSync(cmd, args, { stdio: 'inherit', ...opts, env });
  if (result.error) fail(`spawn ${cmd} failed: ${result.error.message}`);
  if (result.status !== 0) fail(`${cmd} ${args.join(' ')} exited ${result.status}`, result.status || 1);
  return result;
}

function ensureSubDepsInstalled() {
  if (fs.existsSync(SUB_NODE_MODULES)) {
    log('sub-package node_modules already present — skipping install');
    return;
  }
  log('installing @mvanhorn/printing-press into isolated sub-package');
  run('npm', ['install', '--no-audit', '--no-fund'], { cwd: HERE });
}

function ensureSkillsDir() {
  fs.mkdirSync(SKILLS_OUT, { recursive: true });
}

function detectGo() {
  const probe = spawnSync('sh', ['-lc', 'command -v go'], { stdio: 'pipe' });
  return probe.status === 0;
}

function installStarterPack(skillOnly) {
  const binCli = path.join(SUB_NODE_MODULES, '.bin', 'printing-press');
  if (!fs.existsSync(binCli)) {
    fail(`printing-press bin not found at ${binCli} — sub-package install may have failed`);
  }
  // Drop --json so upstream streams human progress (Go compiles 4 CLIs serially;
  // can take several minutes). Re-enable with MADARX_PP_INSTALL_JSON=1 if a
  // caller wants machine-readable output AND can wait silently.
  const installArgs = ['install', 'starter-pack'];
  if (skillOnly) installArgs.push('--skill-only');
  if (process.env.MADARX_PP_INSTALL_JSON === '1') installArgs.push('--json');
  log(`installing starter-pack (${skillOnly ? 'skill-only' : 'full — Go compiles can take 2-5min per CLI'})`);
  run(binCli, installArgs, { cwd: HERE });
}

async function registerStarterPackSlugs() {
  const STARTER_PACK = [
    { slug: 'espn',        desc: 'Live scores, standings, news, box scores, odds across 17 sports.' },
    { slug: 'flight-goat', desc: 'Flight search via Kayak + sniffed Google Flights.' },
    { slug: 'movie-goat',  desc: 'Movie discovery via TMDb + OMDb + streaming availability.' },
    { slug: 'recipe-goat', desc: 'Recipe search across 37 sites with pantry + nutrition.' },
  ];
  let registry;
  try {
    registry = await import('../../lib/printing-press-registry.js');
  } catch (err) {
    log(`registry import failed: ${err.message} (DB may not be initialised yet — slugs not auto-registered)`);
    return;
  }
  fs.mkdirSync(registry.GENERATED_CLIS_DIR, { recursive: true });
  for (const { slug, desc } of STARTER_PACK) {
    const cliPath = path.join(registry.GENERATED_CLIS_DIR, slug);
    fs.mkdirSync(cliPath, { recursive: true });
    try {
      registry.recordInstall({
        slug,
        source_kind: 'starter-pack',
        declared_scopes: ['read'],
        required_secrets: [],
        manifest: { description: desc, upstream: 'go-bin', bin: `${process.env.HOME}/go/bin/${slug}-pp-cli` },
        path: cliPath,
      });
    } catch (err) {
      log(`skip register ${slug}: ${err.message}`);
    }
  }
  log(`registered ${STARTER_PACK.length} starter-pack slugs in printing_press_clis`);
}

async function main() {
  ensureSubDepsInstalled();
  ensureSkillsDir();
  const hasGo = detectGo();
  if (!hasGo) {
    log('Go not on PATH — falling back to --skill-only install.');
    log('For full CLI generation: brew install go && go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest');
  }
  const forced = process.env.MADARX_PP_INSTALL_MODE; // 'full' | 'skill-only'
  const skillOnly = forced === 'skill-only' || (forced !== 'full' && !hasGo);
  installStarterPack(skillOnly);
  await registerStarterPackSlugs();
  log('done.');
}

main().catch((err) => fail(err?.message || String(err)));
