//! Test support (plan §11): a scripted [`Provider`] for deterministic, cost-free
//! tests of the engine, MCP, and web layers — no network, keys, or model spend.
//!
//! Available to this crate's own tests, and to downstream crates that enable the
//! `testing` feature in their dev-dependencies.

use crate::agent::{AgentOutcome, AgentTask};
use crate::config::ProviderId;
use crate::progress::{Event, Progress};
use crate::providers::{AuthStatus, Provider, ProviderKind};
use anyhow::Result;
use async_trait::async_trait;

/// A provider that returns a fixed answer and a scripted model list.
pub struct MockProvider {
    answer: String,
    models: Vec<String>,
}

impl MockProvider {
    pub fn new(answer: impl Into<String>) -> MockProvider {
        MockProvider {
            answer: answer.into(),
            models: vec!["mock-model".to_string()],
        }
    }
}

#[async_trait]
impl Provider for MockProvider {
    fn id(&self) -> ProviderId {
        ProviderId::Anthropic // arbitrary placeholder; only metadata
    }
    fn kind(&self) -> ProviderKind {
        ProviderKind::RawModel
    }

    async fn run_agent(&self, _task: &AgentTask, progress: &dyn Progress) -> Result<AgentOutcome> {
        // Emit a couple of events so progress sinks are exercised too.
        progress.event(Event::tool("read_page", "index.md"));
        progress.event(Event::note("scripted answer"));
        Ok(AgentOutcome {
            final_text: self.answer.clone(),
            tool_calls: 1,
            cost_usd: Some(0.0),
        })
    }

    async fn auth_status(&self) -> AuthStatus {
        AuthStatus::Ok
    }

    async fn list_models(&self) -> Result<Vec<String>> {
        Ok(self.models.clone())
    }
}
