#!/usr/bin/env node
/**
 * cli:gitflow-abort
 * Detects and aborts in-progress git operations (rebase, merge, cherry-pick).
 *
 * Exit codes: 0 = OK, 1 = warnings, 2 = blockers
 *
 * Usage:
 *   npx ts-node index.ts --spec '<json>' [--workdir <path>] [--json]
 */
import { parseArgs } from 'node:util';
import { readFileSync, existsSync } from 'node:fs';
import { validate } from './validate.js';
import { execute } from './execute.js';
import type { AbortResult } from './types.js';

const { values, positionals } = parseArgs({
  options: {
    spec: { type: 'string' },
    workdir: { type: 'string' },
    help: { type: 'boolean', short: 'h' },
    json: { type: 'boolean' },
  },
  allowPositionals: true,
});

if (values.help) {
  console.log(`
cli:gitflow-abort — SmartStack Studio

Detects and aborts in-progress git operations (rebase, merge, cherry-pick).

Usage:
  npx ts-node index.ts --spec '<json>' [--workdir <path>] [--json]

Options:
  --spec        JSON string or path to a JSON file with abort spec
  --workdir     Working directory for git operations (defaults to cwd)
  --json        Output result as JSON
  --help, -h    Show this help
  `);
  process.exit(0);
}

// ── Validate args ─────────────────────────────────────────
const specArg = values.spec;
const workdir = values.workdir || process.cwd();

if (!specArg) {
  const result = { success: false, blockers: ['Missing required arg: --spec'], warnings: [] };
  if (values.json) console.log(JSON.stringify(result, null, 2));
  else console.error('[BLOCKER] Missing required arg: --spec');
  process.exit(2);
}

// ── Parse spec (JSON string or file path) ──────────────────
let rawSpec: unknown;
try {
  if (existsSync(specArg)) {
    rawSpec = JSON.parse(readFileSync(specArg, 'utf-8'));
  } else {
    rawSpec = JSON.parse(specArg);
  }
} catch (err) {
  const result = { success: false, blockers: [`Invalid JSON spec: ${(err as Error).message}`], warnings: [] };
  if (values.json) console.log(JSON.stringify(result, null, 2));
  else console.error(`[BLOCKER] Invalid JSON spec: ${(err as Error).message}`);
  process.exit(2);
}

// ── Validate ──────────────────────────────────────────────
const validation = validate(rawSpec);

if (!validation.valid || !validation.data) {
  const result = { success: false, blockers: validation.blockers, warnings: validation.warnings };
  if (values.json) {
    console.log(JSON.stringify(result, null, 2));
  } else {
    for (const b of validation.blockers) console.error(`[BLOCKER] ${b}`);
    for (const w of validation.warnings) console.warn(`[WARNING] ${w}`);
  }
  process.exit(2);
}

// Log warnings
if (!values.json) {
  for (const w of validation.warnings) console.warn(`[WARNING] ${w}`);
}

// ── Execute ───────────────────────────────────────────────
let result: AbortResult;
try {
  result = await execute(validation.data, workdir);
} catch (err) {
  const errResult = { success: false, operation: 'none' as const, restored: false, error: (err as Error).message };
  if (values.json) console.log(JSON.stringify(errResult, null, 2));
  else console.error(`[BLOCKER] ${(err as Error).message}`);
  process.exit(2);
}

// ── Output ────────────────────────────────────────────────
if (values.json) {
  console.log(JSON.stringify(result, null, 2));
} else {
  if (result.success) {
    if (result.operation === 'none') {
      console.log('✓ No in-progress operation');
    } else {
      console.log(`✓ ${result.operation} aborted successfully`);
    }
  } else {
    console.error(`✗ Failed to abort ${result.operation}: ${result.error}`);
  }
}

process.exit(result.success ? 0 : 2);
