#!/usr/bin/env node
/**
 * cli:efcore-apply — Apply EF Core migrations to the database, GATED by the 3-tier
 * migration policy (migration-policy.ts).
 *
 *   🟢 local dev DB             → applies pending migrations autonomously
 *   🟡 down-migration (local)   → needs "confirm": true
 *   🔴 remote/unknown DB        → refused ({ blocked: true }); a human deploys
 *
 * Usage:
 *   npx --prefer-offline tsx skills/efcore/cli/apply/index.ts --spec '{
 *     "cwd": "D:/path/to/worktree"
 *   }'
 *   # revert (down-migration), requires confirm:
 *   ... --spec '{"cwd":"...","targetMigration":"<Name|0>","confirm":true}'
 */
import { parseArgs } from 'node:util';
import { existsSync, readFileSync } from 'node:fs';
import { validate } from './validate.js';
import { execute } from './execute.js';

async function main(): Promise<void> {
  const { values } = parseArgs({
    options: {
      spec: { type: 'string' },
      help: { type: 'boolean', short: 'h' },
    },
  });

  if (values.help || !values.spec) {
    console.log(`Usage: npx --prefer-offline tsx skills/efcore/cli/apply/index.ts --spec '{"cwd":"..."}'`);
    process.exit(values.help ? 0 : 1);
  }

  let raw: unknown;
  try {
    raw = existsSync(values.spec!) ? JSON.parse(readFileSync(values.spec!, 'utf-8')) : JSON.parse(values.spec!);
  } catch (err) {
    console.log(JSON.stringify({ success: false, errors: [`Invalid JSON: ${(err as Error).message}`], warnings: [] }, null, 2));
    process.exit(1);
  }

  const validation = validate(raw);
  if (!validation.valid || !validation.data) {
    console.log(JSON.stringify({ success: false, errors: validation.blockers, warnings: validation.warnings }, null, 2));
    process.exit(1);
  }

  const result = await execute(validation.data);
  console.log(JSON.stringify(result, null, 2));
  process.exit(result.success ? 0 : 1);
}

void main();
