//! NoOp Connector Operations for Testing
//!
//! This module provides a stub implementation of `ConnectorOperations` that
//! can be used for testing the RPC handler without actual connector access.

use async_trait::async_trait;
use tracing::debug;

use crate::error::AcpServerError;

use super::types::{ConnectorInfo, ConnectorOperations, SessionInfo};

/// A no-op implementation of ConnectorOperations for testing
///
/// This stub provides minimal implementations that return success without
/// actually doing anything. Useful for unit testing the RPC dispatch logic.
#[derive(Debug, Clone, Copy, Default)]
pub struct NoOpConnectorOperations;

#[async_trait]
impl ConnectorOperations for NoOpConnectorOperations {
    async fn create_session(
        &self,
        connector_id: &str,
        _cwd: Option<String>,
        _ownership: dirigent_protocol::SessionOwnership,
    ) -> Result<SessionInfo, AcpServerError> {
        Ok(SessionInfo {
            session_id: uuid::Uuid::new_v4().to_string(),
            title: Some("New Session".to_string()),
            connector_id: connector_id.to_string(),
            cwd: None,
            created_at: chrono::Utc::now().to_rfc3339(),
            models: None,
            modes: None,
        })
    }

    async fn load_session(
        &self,
        connector_id: &str,
        session_id: &str,
        _cwd: Option<String>,
        _mcp_servers: Option<serde_json::Value>,
    ) -> Result<SessionInfo, AcpServerError> {
        Ok(SessionInfo {
            session_id: session_id.to_string(),
            title: Some("Loaded Session".to_string()),
            connector_id: connector_id.to_string(),
            cwd: None,
            created_at: chrono::Utc::now().to_rfc3339(),
            models: None,
            modes: None,
        })
    }

    async fn send_message(
        &self,
        _connector_id: &str,
        _session_id: &str,
        text: String,
    ) -> Result<String, AcpServerError> {
        debug!("NoOp: send_message - {} chars", text.len());
        Ok("end_turn".to_string())
    }

    async fn cancel_generation(
        &self,
        _connector_id: &str,
        _session_id: &str,
    ) -> Result<(), AcpServerError> {
        debug!("NoOp: cancel_generation");
        Ok(())
    }

    async fn list_connectors(&self) -> Result<Vec<ConnectorInfo>, AcpServerError> {
        Ok(vec![ConnectorInfo {
            id: "stub-connector".to_string(),
            name: "Stub Connector".to_string(),
            connector_type: "stub".to_string(),
            available: true,
        }])
    }

    async fn default_connector_id(&self) -> Option<String> {
        Some("stub-connector".to_string())
    }

    async fn get_connector_commands(
        &self,
        _connector_id: &str,
    ) -> Result<Vec<crate::sse::SlashCommand>, AcpServerError> {
        // Return a stub list of commands
        Ok(vec![crate::sse::SlashCommand {
            name: "echo".to_string(),
            description: "Echo command (stub)".to_string(),
            input: None,
        }])
    }

    async fn send_agent_response(
        &self,
        connector_id: &str,
        request_id: serde_json::Value,
        _response: serde_json::Value,
    ) -> Result<(), AcpServerError> {
        debug!(
            "NoOp: send_agent_response - connector: {}, request: {}",
            connector_id, request_id
        );
        Ok(())
    }

    async fn get_session_metadata(
        &self,
        _connector_id: &str,
        _session_id: &str,
    ) -> Result<
        (
            Option<dirigent_protocol::SessionModelState>,
            Option<dirigent_protocol::SessionModeState>,
        ),
        AcpServerError,
    > {
        debug!("NoOp: get_session_metadata");
        // Return None for both - no metadata available in stub
        Ok((None, None))
    }

    async fn set_session_mode(
        &self,
        _connector_id: &str,
        _session_id: &str,
        mode_id: &str,
    ) -> Result<(), AcpServerError> {
        debug!("NoOp: set_session_mode - mode_id: {}", mode_id);
        Ok(())
    }

    async fn set_session_model(
        &self,
        _connector_id: &str,
        _session_id: &str,
        model_id: &str,
    ) -> Result<(), AcpServerError> {
        debug!("NoOp: set_session_model - model_id: {}", model_id);
        Ok(())
    }

    async fn get_connector_agent_type(
        &self,
        _connector_id: &str,
    ) -> Result<Option<String>, AcpServerError> {
        debug!("NoOp: get_connector_agent_type");
        Ok(None)
    }

    async fn list_sessions(
        &self,
        connector_id: &str,
    ) -> Result<Vec<SessionInfo>, AcpServerError> {
        debug!("NoOp: list_sessions for connector: {}", connector_id);
        Ok(vec![
            SessionInfo {
                session_id: "stub-session-1".to_string(),
                title: Some("Stub Session".to_string()),
                connector_id: connector_id.to_string(),
                cwd: None,
                created_at: chrono::Utc::now().to_rfc3339(),
                models: None,
                modes: None,
            },
        ])
    }

    async fn resolve_session_connector(&self, _session_id: &str) -> Option<String> {
        debug!("NoOp: resolve_session_connector");
        None
    }

    async fn list_all_sessions(&self) -> Result<Vec<SessionInfo>, AcpServerError> {
        debug!("NoOp: list_all_sessions");
        Ok(vec![])
    }
}
