#!/usr/bin/env node
/**
 * cli:scaffold-tests
 * Responsabilité : Generate test files per architectural layer
 * Appelé par Claude Code via skill:development-testing
 *
 * Usage :
 *   npx --prefer-offline tsx skills/development/testing/cli/scaffold-tests/index.ts \
 *     --spec '{"layer":"business","module":"hrm","appCode":"MyApp","entities":[...],"businessRules":[...],"projectPath":"/path"}'
 */
import { parseArgs } from 'node:util'
import { mkdirSync, writeFileSync } from 'node:fs'
import { dirname, resolve, join } from 'node:path'
import { validate } from './validate.js'
import { generate } from './generate.js'
import type { ScaffoldTestsInput } from './types.js'
import { generateEnvelope, failGenerate, printEnvelope } from '../../../../lib/output.js'

const COMMAND = 'scaffold-tests'

function main(): void {
  const { values } = parseArgs({
    options: {
      spec: { type: 'string' },
      outdir: { type: 'string' },
      dry_run: { type: 'boolean', default: false },
    },
    strict: true,
  })

  if (!values.spec) {
    printEnvelope(failGenerate(COMMAND, ['--spec is required']))
    process.exit(1)
  }

  let raw: unknown
  try {
    raw = JSON.parse(values.spec)
  } catch {
    printEnvelope(failGenerate(COMMAND, ['Invalid JSON in --spec']))
    process.exit(1)
  }

  const validation = validate(raw)
  if (!validation.valid) {
    printEnvelope(failGenerate(COMMAND, validation.errors))
    process.exit(1)
  }

  const spec = raw as ScaffoldTestsInput
  const files = generate(spec)

  if (values.dry_run) {
    printEnvelope(generateEnvelope(COMMAND, {
      data: { dryRun: true, fileCount: files.length, files: files.map(f => f.path) },
      warnings: validation.warnings,
    }))
    process.exit(0)
  }

  const outdir = values.outdir ?? spec.projectPath
  const writtenPaths: string[] = []

  for (const file of files) {
    const fullPath = resolve(join(outdir, file.path))
    mkdirSync(dirname(fullPath), { recursive: true })
    writeFileSync(fullPath, file.content, 'utf-8')
    writtenPaths.push(fullPath)
  }

  printEnvelope(generateEnvelope(COMMAND, {
    data: { layer: spec.layer, fileCount: writtenPaths.length },
    filesCreated: writtenPaths,
    warnings: validation.warnings,
    nextSteps: [`Run tests: dotnet test --filter Category=${capitalize(spec.layer)}`],
  }))
}

function capitalize(s: string): string {
  return s.charAt(0).toUpperCase() + s.slice(1)
}

main()
