/**
 * Verifier Types
 *
 * Zod schemas and TypeScript types for the verifier system.
 */

import { z } from 'zod';

/**
 * Verifier type - command or LLM based
 */
export const VerifierTypeSchema = z.enum(['command', 'llm']);
export type VerifierType = z.infer<typeof VerifierTypeSchema>;

/**
 * Configuration for a single verifier
 */
export const VerifierConfigSchema = z.object({
  /** Verifier type */
  type: VerifierTypeSchema,
  /** Unique name for this verifier */
  name: z.string().min(1),
  /** Shell command to execute (for command type) */
  command: z.string().optional(),
  /** LLM prompt (for llm type) */
  prompt: z.string().optional(),
  /** Execution timeout in seconds */
  timeout: z.number().int().positive().default(120),
  /** Whether to pass on exit code 0 (for command type) */
  passOnExit0: z.boolean().default(true),
  /** Whether this verifier is enabled */
  enabled: z.boolean().default(true),
});

export type VerifierConfig = z.infer<typeof VerifierConfigSchema>;

/**
 * Full verifiers configuration file schema
 */
export const VerifiersConfigSchema = z.object({
  /** List of verifier configurations */
  verifiers: z.array(VerifierConfigSchema).default([]),
  /** Maximum verification attempts (0 = infinite) */
  maxAttempts: z.number().int().nonnegative().default(3),
});

export type VerifiersConfig = z.infer<typeof VerifiersConfigSchema>;

/**
 * Issue extracted from verifier output
 */
export interface VerifierIssue {
  /** Issue message */
  message: string;
  /** File path if identified */
  file?: string;
  /** Line number if identified */
  line?: number;
  /** Issue severity */
  severity?: 'error' | 'warning' | 'info';
}

/**
 * Result from running a single verifier
 */
export interface VerifierResult {
  /** Verifier name */
  name: string;
  /** Whether verification passed */
  passed: boolean;
  /** Command/LLM output */
  output: string;
  /** Execution duration in seconds */
  duration: number;
  /** Extracted issues */
  issues: VerifierIssue[];
  /** Error message if execution failed */
  error?: string;
}

/**
 * Context provided to verifiers
 */
export interface VerificationContext {
  /** Original goal/task being verified */
  goal?: string;
  /** List of files that were changed */
  filesChanged?: string[];
  /** Git diff of changes */
  gitDiff?: string;
  /** Working directory */
  cwd?: string;
}

/**
 * Complete verification report
 */
export interface VerificationReport {
  /** Results from all verifiers */
  results: VerifierResult[];
  /** Whether all verifiers passed */
  allPassed: boolean;
  /** Human-readable summary */
  summary: string;
  /** Total execution duration in seconds */
  totalDuration: number;
  /** Number of passed verifiers */
  passedCount: number;
  /** Number of failed verifiers */
  failedCount: number;
}

/**
 * Get status icon for a result
 */
export function getStatusIcon(passed: boolean): string {
  return passed ? '✓' : '✗';
}

/**
 * Create a verification report from results
 */
export function createReport(results: VerifierResult[]): VerificationReport {
  const passedCount = results.filter((r) => r.passed).length;
  const failedCount = results.length - passedCount;
  const totalDuration = results.reduce((sum, r) => sum + r.duration, 0);
  const allPassed = failedCount === 0;

  const summary = allPassed
    ? `All ${results.length} verifier(s) passed`
    : `${failedCount}/${results.length} verifier(s) failed`;

  return {
    results,
    allPassed,
    summary,
    totalDuration,
    passedCount,
    failedCount,
  };
}

/**
 * Get failed results from a report
 */
export function getFailures(report: VerificationReport): VerifierResult[] {
  return report.results.filter((r) => !r.passed);
}

/**
 * Get all issues from a report
 */
export function getAllIssues(report: VerificationReport): VerifierIssue[] {
  return report.results.flatMap((r) => r.issues);
}
