/**
 * AirCoding Provider Contracts
 *
 * Implements ProviderCapabilityMatrix, ModelRequirement, ProviderCompletionInput,
 * ProviderStreamEvent, ProviderAdapter, and ProviderManager interfaces
 * per interface-contracts-v1.md §15 and system-detailed-design.md §22.6.
 */

// Import IDs needed for these types
import type {
  ProviderID,
  ModelID,
  JsonObject,
} from './ids'

// =============================================================================
// §15 — Provider Contracts
// =============================================================================

/**
 * Provider kind types supported by the system.
 * Matches provider-capability-matrix-v1.md §2.
 */
export type ProviderKind =
  | 'anthropic'
  | 'openai'
  | 'openrouter'
  | 'ollama'
  | 'anthropic_compatible'
  | 'openai_compatible'
  | 'custom'

/**
 * Quality tier classification for models.
 */
export type QualityTier = 'frontier' | 'strong' | 'standard' | 'cheap' | 'local' | 'unknown'

/**
 * Cost tier classification for models.
 */
export type CostTier = 'high' | 'medium' | 'low' | 'free' | 'unknown'

/**
 * Provider identity - core provider metadata.
 * Matches provider-capability-matrix-v1.md §2.
 */
export interface ProviderIdentity {
  provider_id: ProviderID
  provider_kind: ProviderKind
  display_name: string
  base_url?: string
  auth_ref?: string
  local: boolean
}

/**
 * Capability matrix for a specific model on a provider.
 * Matches interface-contracts-v1.md §15 and provider-capability-matrix-v1.md §3.
 */
export interface ProviderCapabilityMatrix {
  provider_id: ProviderID
  provider_kind: ProviderKind
  model_id: ModelID
  display_name?: string
  enabled: boolean
  quality_tier: QualityTier
  cost_tier: CostTier
  context_window_tokens?: number
  max_output_tokens?: number
  supports: ProviderSupports
  conversion: ProviderConversion
  limits?: ProviderLimits
  default_use?: ProviderDefaultUse
  notes?: string[]
}

/**
 * Supported capabilities for a model.
 * Per provider-capability-matrix-v1.md §3.
 */
export interface ProviderSupports {
  text_input: boolean
  text_output: boolean
  streaming: boolean
  tool_use: boolean
  parallel_tool_use: boolean
  structured_output: boolean
  json_mode: boolean
  thinking: boolean
  prompt_cache: boolean
  system_prompt: boolean
  image_input: boolean
  image_output: boolean
  audio_input: boolean
  audio_output: boolean
  file_input: boolean
  computer_use: boolean
  long_context: boolean
  batch: boolean
}

/**
 * Conversion behavior for provider adapter.
 * Per provider-capability-matrix-v1.md §3.
 */
export interface ProviderConversion {
  from_anthropic_canonical: 'lossless' | 'lossy' | 'unsupported'
  tool_schema: 'native' | 'converted' | 'emulated' | 'unsupported'
  image_input: 'native' | 'artifact_link' | 'unsupported'
  thinking: 'native' | 'stripped' | 'unsupported'
  cache_control: 'native' | 'ignored' | 'unsupported'
}

/**
 * Rate limits for a model.
 * Per provider-capability-matrix-v1.md §3.
 */
export interface ProviderLimits {
  requests_per_minute?: number
  tokens_per_minute?: number
  concurrent_requests?: number
  max_tool_schema_bytes?: number
  max_image_count?: number
  max_file_bytes?: number
}

/**
 * Default use cases for a model.
 * Per provider-capability-matrix-v1.md §3.
 */
export interface ProviderDefaultUse {
  main?: boolean
  architecture?: boolean
  execute?: boolean
  review?: boolean
  debug?: boolean
  compact?: boolean
  mine_experience?: boolean
}

/**
 * Model requirement specification for task execution.
 * Per interface-contracts-v1.md §15 and provider-capability-matrix-v1.md §5.
 */
export interface ModelRequirement {
  required: Partial<ProviderSupports>
  preferred?: Partial<ProviderSupports>
  min_quality_tier?: 'frontier' | 'strong' | 'standard' | 'cheap' | 'local'
  max_cost_tier?: 'high' | 'medium' | 'low' | 'free'
  min_context_window_tokens?: number
  allow_lossy_conversion?: boolean
}

/**
 * Model assignment mode - how the model was selected.
 * Per provider-capability-matrix-v1.md §6.
 */
export type ModelAssignmentMode = 'scheduler_forced' | 'agent_select'

/**
 * Model assignment - the selected model for a task.
 * Per interface-contracts-v1.md §9 and §15, and provider-capability-matrix-v1.md §6.
 * Note: This is also defined in task.ts for scheduler use - this re-export ensures
 * both modules have access to the same type definition.
 */
export interface ModelAssignment {
  mode: ModelAssignmentMode
  provider_id?: ProviderID
  model_id?: ModelID
  allowed_models?: Array<{ provider_id: ProviderID; model_id: ModelID }>
  requirement: ModelRequirement
  reason: string
}

/**
 * Input for a provider completion request.
 * Per interface-contracts-v1.md §15 and provider-capability-matrix-v1.md §7.
 */
export interface ProviderCompletionInput {
  provider_id: ProviderID
  model_id: ModelID
  canonical_format: 'anthropic'
  messages: unknown[]
  tools?: unknown[]
  tool_choice?: unknown
  system?: unknown
  max_output_tokens?: number
  temperature?: number
  metadata?: JsonObject
}

/**
 * Stream event types from provider.
 * Per interface-contracts-v1.md §15.
 */
export type ProviderStreamEventType =
  | 'message_start'
  | 'content_delta'
  | 'tool_use'
  | 'message_stop'
  | 'error'

/**
 * A stream event from the provider.
 * Per interface-contracts-v1.md §15.
 */
export interface ProviderStreamEvent {
  type: ProviderStreamEventType
  payload: unknown
}

/**
 * Conversion report for provider adaptation.
 * Per provider-capability-matrix-v1.md §8.
 */
export interface ProviderConversionReport {
  status: 'lossless' | 'lossy' | 'unsupported'
  omissions: string[]
  warnings: string[]
  required_confirmation?: boolean
}

/**
 * Provider adapter interface - the contract for all LLM provider implementations.
 * Per interface-contracts-v1.md §15 and system-detailed-design.md §22.6.
 *
 * Adapter responsibilities (per provider-capability-matrix-v1.md §7):
 * 1. Convert Anthropic canonical messages to provider format.
 * 2. Convert provider output back to Anthropic canonical content blocks or RuntimeEvents.
 * 3. Validate tool-call and structured-output compatibility.
 * 4. Record conversion omissions/losses.
 * 5. Never leak credentials into logs, events, artifacts, or model-visible messages.
 */
export interface ProviderAdapter {
  /** Unique identifier for this adapter instance */
  provider_id: ProviderID

  /**
   * List all available models for this provider.
   * Returns capability matrix for each model.
   */
  list_models(): Promise<ProviderCapabilityMatrix[]>

  /**
   * Validate and get capability matrix for a specific model.
   * @throws Error if model is not available
   */
  validate_model(model_id: ModelID): Promise<ProviderCapabilityMatrix>

  /**
   * Execute a completion request.
   * Yields stream events as they arrive from the provider.
   */
  complete(input: ProviderCompletionInput): AsyncIterable<ProviderStreamEvent>

  /**
   * Optional: Count tokens for a given input.
   * Useful for context budgeting and cost estimation.
   */
  count_tokens?(input: unknown): Promise<number>
}

/**
 * Provider manager interface - the orchestration layer for model selection and completion.
 * Per interface-contracts-v1.md §15 and system-detailed-design.md §12.1.
 *
 * The ProviderManager is the runtime facade that:
 * - Loads and manages provider configuration
 * - Selects appropriate models based on requirements
 * - Routes completion requests to the appropriate adapter
 */
export interface ProviderManager {
  /**
   * Load provider configuration from global and project sources.
   * Should be called at startup or when configuration changes.
   */
  load_config(): Promise<void>

  /**
   * Select an appropriate model based on requirements.
   * @returns ModelAssignment with the selected provider/model
   */
  select_model(requirement: ModelRequirement): Promise<ModelAssignment>

  /**
   * Execute a completion request.
   * Yields normalized stream events.
   */
  complete(input: ProviderCompletionInput): AsyncIterable<ProviderStreamEvent>
}