/**
 * Agent error classes
 * Errors specific to agent execution and iteration
 */

import { ExecutionError } from '../base/errors'

/**
 * Thrown when agent initialization fails
 *
 * Severity: critical (agent cannot start without proper initialization)
 * Category: agent
 *
 * @example
 * ```typescript
 * throw new AgentInitializationError(
 *   'Failed to initialize agent: Invalid LLM configuration',
 *   {
 *     agentId: 'agent-123',
 *     reason: 'missing_api_key',
 *     llmModel: 'gpt-4'
 *   }
 * )
 * ```
 */
export class AgentInitializationError extends ExecutionError {
  readonly type = 'agent_initialization_error' as const
  readonly severity = 'critical' as const
  readonly category = 'agent' as const

  constructor(message: string, context?: Record<string, unknown>) {
    super(message, context)
  }
}

/**
 * Thrown when an agent iteration fails during execution
 *
 * Severity: warning (iteration failure that may be retried or requires user intervention)
 * Category: agent
 *
 * @example
 * ```typescript
 * throw new AgentIterationError(
 *   'Agent iteration failed: Tool execution timeout',
 *   {
 *     agentId: 'agent-123',
 *     iterationNumber: 5,
 *     toolName: 'web_search',
 *     attemptCount: 2
 *   }
 * )
 * ```
 */
export class AgentIterationError extends ExecutionError {
  readonly type = 'agent_iteration_error' as const
  readonly severity = 'warning' as const
  readonly category = 'agent' as const

  constructor(message: string, context?: Record<string, unknown>) {
    super(message, context)
  }
}

/**
 * Thrown when agent completion phase fails
 *
 * Severity: warning (completion failure that may require retry or user intervention)
 * Category: agent
 *
 * @example
 * ```typescript
 * throw new AgentCompletionError(
 *   'Failed to generate final output: LLM timeout',
 *   {
 *     agentId: 'agent-123',
 *     attempts: 1,
 *     reason: 'llm_timeout'
 *   }
 * )
 * ```
 */
export class AgentCompletionError extends ExecutionError {
  readonly type = 'agent_completion_error' as const
  readonly severity = 'warning' as const
  readonly category = 'agent' as const

  constructor(message: string, context?: Record<string, unknown>) {
    super(message, context)
  }
}

/**
 * Thrown when agent output validation fails
 *
 * Severity: info (validation failure indicating agent output doesn't meet expected schema)
 * Category: validation
 *
 * @example
 * ```typescript
 * throw new AgentOutputValidationError(
 *   'Agent output validation failed: Missing required field "result"',
 *   {
 *     agentId: 'agent-123',
 *     iterationNumber: 3,
 *     expectedSchema: 'CompletionSchema',
 *     field: 'result'
 *   }
 * )
 * ```
 */
export class AgentOutputValidationError extends ExecutionError {
  readonly type = 'agent_output_validation_error' as const
  readonly severity = 'info' as const
  readonly category = 'validation' as const

  constructor(message: string, context?: Record<string, unknown>) {
    super(message, context)
  }
}

/**
 * Thrown when agent exceeds maximum iterations without completing
 *
 * Severity: critical (agent failed to complete within allowed iterations)
 * Category: agent
 *
 * @example
 * ```typescript
 * throw new AgentMaxIterationsError(
 *   'Agent exceeded maximum iterations (10)',
 *   {
 *     maxIterations: 10,
 *     currentIteration: 10
 *   }
 * )
 * ```
 */
export class AgentMaxIterationsError extends ExecutionError {
  readonly type = 'agent_max_iterations_error' as const
  readonly severity = 'critical' as const
  readonly category = 'agent' as const

  constructor(message: string, context?: { maxIterations: number; currentIteration: number }) {
    super(message, context)
  }
}

/**
 * Thrown when agent execution exceeds its configured timeout ceiling
 *
 * Severity: critical (execution terminated, no further iterations)
 * Category: agent
 *
 * @example
 * ```typescript
 * throw new AgentTimeoutError(
 *   'Agent execution exceeded timeout (300000ms)',
 *   {
 *     timeout: 300000,
 *     iteration: 3
 *   }
 * )
 * ```
 */
export class AgentTimeoutError extends ExecutionError {
  readonly type = 'agent_timeout_error' as const
  readonly severity = 'critical' as const
  readonly category = 'agent' as const

  constructor(message: string, context?: { timeout: number; iteration: number }) {
    super(message, context)
  }
}

/**
 * Thrown when a user cancels a running execution via the cancel endpoint.
 * The AbortController fires with reason 'user_cancellation', which the
 * iterate() between-iteration check distinguishes from 'timeout'.
 *
 * Severity: warning (user-initiated, not an unexpected failure)
 * Category: agent
 *
 * @example
 * ```typescript
 * throw new AgentCancellationError('Execution cancelled by user', { iteration: 3 })
 * ```
 */
export class AgentCancellationError extends ExecutionError {
  readonly type = 'agent_cancellation_error' as const
  readonly severity = 'warning' as const
  readonly category = 'agent' as const

  constructor(message: string, context?: { iteration: number }) {
    super(message, context)
  }
}

/**
 * Thrown when a running execution is flagged as stalled by the heartbeat
 * monitor (pg_cron). The AbortController fires with reason 'stalled',
 * which the iterate() between-iteration check distinguishes from 'timeout'.
 *
 * Severity: critical (execution terminated, no further iterations)
 * Category: agent
 *
 * @example
 * ```typescript
 * throw new AgentStalledError(
 *   'Execution stalled: no heartbeat received within threshold',
 *   { iteration: 5 }
 * )
 * ```
 */
export class AgentStalledError extends ExecutionError {
  readonly type = 'agent_stalled_error' as const
  readonly severity = 'critical' as const
  readonly category = 'agent' as const

  constructor(message: string, context?: { iteration: number }) {
    super(message, context)
  }
}

/**
 * Thrown when memory entry validation fails
 *
 * Severity: info (validation failure indicating improper memory entry structure)
 * Category: validation
 *
 * @example
 * ```typescript
 * throw new AgentMemoryValidationError(
 *   'turnNumber required for history entries (use null for session memory)',
 *   {
 *     entryType: 'reasoning',
 *     missingField: 'turnNumber',
 *     iterationNumber: 1
 *   }
 * )
 * ```
 */
export class AgentMemoryValidationError extends ExecutionError {
  readonly type = 'agent_memory_validation_error' as const
  readonly severity = 'info' as const
  readonly category = 'validation' as const

  constructor(message: string, context?: Record<string, unknown>) {
    super(message, context)
  }
}
