/**
 * cli:scaffold-tests-from-ac — validate.ts
 *
 * Two-stage: (a) Zod schema validation on the input spec,
 * (b) Filesystem existence checks (moduleDir + projectPath must exist).
 *
 * Returns a {valid, errors[], warnings[], data} envelope. No side effects.
 */

import { existsSync, statSync } from 'node:fs'
import { ScaffoldTestsFromAcSpecSchema, type ScaffoldTestsFromAcSpec } from './types.js'

export interface ValidationResult {
  valid: boolean
  errors: string[]
  warnings: string[]
  data?: ScaffoldTestsFromAcSpec
}

export function validate(raw: unknown): ValidationResult {
  // Stage A — Zod
  const parsed = ScaffoldTestsFromAcSpecSchema.safeParse(raw)
  if (!parsed.success) {
    const errors = parsed.error.issues.map(i => `${i.path.join('.') || '(root)'}: ${i.message}`)
    return { valid: false, errors, warnings: [] }
  }
  const spec = parsed.data
  const errors: string[] = []
  const warnings: string[] = []

  // Stage B — Filesystem
  if (!existsSync(spec.moduleDir)) {
    errors.push(`moduleDir does not exist: ${spec.moduleDir}`)
  } else if (!statSync(spec.moduleDir).isDirectory()) {
    errors.push(`moduleDir is not a directory: ${spec.moduleDir}`)
  }

  if (!existsSync(spec.projectPath)) {
    errors.push(`projectPath does not exist: ${spec.projectPath}`)
  } else if (!statSync(spec.projectPath).isDirectory()) {
    errors.push(`projectPath is not a directory: ${spec.projectPath}`)
  }

  // Soft check: namespace shape (informational)
  if (spec.namespace && !/^[A-Z][A-Za-z0-9]*(\.[A-Z][A-Za-z0-9]*)+$/.test(spec.namespace)) {
    warnings.push(
      `namespace "${spec.namespace}" does not look like Pascal.Dot.Notation — accepted as-is, but emitted code may not compile.`
    )
  }

  return {
    valid: errors.length === 0,
    errors,
    warnings,
    data: errors.length === 0 ? spec : undefined,
  }
}
