#!/usr/bin/env node
/**
 * cli:cross-validate-stack
 * Cross-stack validation backend .NET / frontend React — 5 consistency checks.
 *
 * Usage:
 *   npx --prefer-offline tsx skills/validation/cross-validate/cli/index.ts --specs <directory> --src <directory>
 *
 * Exit codes:
 *   0  Success (0 errors)
 *   1  Errors detected
 *   2  Internal CLI error / input validation
 */
import { parseArgs } from 'node:util'
import { resolve } from 'node:path'
import { validate } from './validate'
import { execute } from './execute'
import { executeEnvelope, failExecute, printEnvelope } from '../../../lib/output.js'

const COMMAND = 'cross-validate-stack'

const { values } = parseArgs({
  options: {
    specs: { type: 'string' },
    src: { type: 'string' },
    help: { type: 'boolean', short: 'h' },
  },
  strict: true,
})

if (values.help) {
  const paren = String.fromCharCode(41)
  console.log(`cli:cross-validate-stack — SmartStack Studio

Cross-stack validation backend .NET / frontend React (5 checks${paren}.

Usage:
  npx --prefer-offline tsx index.ts --specs <directory> --src <directory>

Options:
  --specs    Directory containing the JSON specs (meta.json, endpoints.json, permissions.json${paren} (required${paren}
  --src      Directory containing the .cs and .ts/.tsx source code (required${paren}
  -h, --help Show this help

Checks:
  1. routes-have-endpoints     Every spec endpoint has a .NET controller
  2. endpoints-are-consumed    Every .NET endpoint is called by a React service
  3. permissions-aligned       [RequirePermission] .NET = PermissionGuard/usePermission React
  4. resources-have-screens    Every resource has a controller + a React page
  5. rbac-consistent           Declared permissions = permissions used in the code

Exit codes:
  0  Success (0 errors${paren}
  1  Errors detected
  2  Internal CLI error`)
  process.exit(0)
}

if (!values.specs) {
  printEnvelope(failExecute(COMMAND, ['--specs is required']))
  process.exit(2)
}

if (!values.src) {
  printEnvelope(failExecute(COMMAND, ['--src is required']))
  process.exit(2)
}

const specsPath = resolve(values.specs)
const srcPath = resolve(values.src)

const validation = validate({ specs: specsPath, src: srcPath })

if (!validation.valid) {
  printEnvelope(failExecute(COMMAND, validation.blockers))
  process.exit(2)
}

const report = execute(validation.data!)

if (report.errors === 0) {
  printEnvelope(executeEnvelope(COMMAND, { report, warnings: report.warnings > 0 ? [`${report.warnings} warning(s)`] : [] }))
} else {
  printEnvelope({ ...failExecute(COMMAND, [`${report.errors} error(s) detected`]), report })
}

process.exit(report.errors > 0 ? 1 : 0)
