#!/usr/bin/env node
/**
 * cli:roslyn-validator
 * Analyse statique C# SmartStack — verifie conventions par layer (SS001-SS010).
 *
 * Usage :
 *   npx tsx skills/validation/roslyn/cli/index.ts --src <directory> [--layer <filter>]
 *
 * Exit codes :
 *   0  Succes (0 erreurs)
 *   1  Erreurs detectees
 *   2  Erreur interne CLI / validation input
 */
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 = 'roslyn-validator'

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

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

Analyse statique C# SmartStack (SS001-SS010${paren}.

Usage:
  npx tsx index.ts --src <directory> [--layer <filter>]

Options:
  --src      Repertoire contenant les fichiers .cs (requis${paren}
  --layer    Filtre optionnel: controller, service, repository, entity, all (defaut: all${paren}
  -h, --help Affiche cette aide

Rules:
  SS001  Controller herite ControllerBase + [ApiController]
  SS002  Injection unique IService (pas DbContext${paren}
  SS003  [NavRoute] present et format module.section
  SS004  [RequirePermission] sur chaque endpoint public
  SS005  Retourne DTOs, jamais entites
  SS006  CancellationToken dernier parametre async
  SS007  NavRoute unique dans le projet
  SS008  Service sans DbContext
  SS009  Repository sans logique metier
  SS010  Entity herite BaseEntity

Exit codes:
  0  Succes (0 erreurs${paren}
  1  Erreurs detectees
  2  Erreur interne CLI`)
  process.exit(0)
}

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

const srcPath = resolve(values.src)

const validation = validate({ src: srcPath, layer: values.layer || 'all' })

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)
