//! Communication channel implementations
//! 通信通道实现
//!
//! This module provides concrete implementations of the CommunicationChannel trait
//! for different transport mechanisms.
//!
//! 此模块为不同的传输机制提供 CommunicationChannel trait 的具体实现。

use async_trait::async_trait;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::RwLock;

use super::{
    ChannelConfig, ChannelStats, CommunicationChannel, CommunicationError, CommunicationResult,
    RuntimeInstanceId, RuntimeMessage,
};

/// Unix Domain Socket communication channel
/// Unix Domain Socket 通信通道
pub struct UnixSocketChannel {
    /// Instance identifier for this channel
    /// 此通道的实例标识符
    instance_id: RuntimeInstanceId,
    _config: ChannelConfig,
    stats: Arc<RwLock<ChannelStats>>,
    connected: Arc<RwLock<bool>>,
    start_time: Instant,
}

impl UnixSocketChannel {
    /// Create a new Unix socket channel
    /// 创建新的 Unix socket 通道
    pub fn new(instance_id: RuntimeInstanceId, config: ChannelConfig) -> CommunicationResult<Self> {
        Ok(Self {
            instance_id,
            _config: config,
            stats: Arc::new(RwLock::new(ChannelStats::default())),
            connected: Arc::new(RwLock::new(false)),
            start_time: Instant::now(),
        })
    }

    /// Get the instance ID for this channel
    /// 获取此通道的实例ID
    pub fn instance_id(&self) -> &RuntimeInstanceId {
        &self.instance_id
    }

    /// Connect to the Unix socket
    /// 连接到 Unix socket
    pub async fn connect(&self) -> CommunicationResult<()> {
        // TODO: Implement actual Unix socket connection
        // TODO: 实现实际的 Unix socket 连接
        let mut connected = self.connected.write().await;
        *connected = true;
        Ok(())
    }
}

#[async_trait]
impl CommunicationChannel for UnixSocketChannel {
    async fn send(&self, _message: RuntimeMessage) -> CommunicationResult<()> {
        if !self.is_connected().await {
            return Err(CommunicationError::ChannelClosed);
        }

        // TODO: Implement actual message sending
        // TODO: 实现实际的消息发送

        // Update statistics / 更新统计信息
        let mut stats = self.stats.write().await;
        stats.messages_sent += 1;

        Ok(())
    }

    async fn receive(&self) -> CommunicationResult<RuntimeMessage> {
        if !self.is_connected().await {
            return Err(CommunicationError::ChannelClosed);
        }

        // TODO: Implement actual message receiving
        // TODO: 实现实际的消息接收

        // Update statistics / 更新统计信息
        let mut stats = self.stats.write().await;
        stats.messages_received += 1;

        // Return a dummy message for now / 暂时返回一个虚拟消息
        Ok(RuntimeMessage::Ack {
            request_id: "dummy".to_string(),
        })
    }

    async fn request_response(
        &self,
        request: RuntimeMessage,
        timeout: Duration,
    ) -> CommunicationResult<RuntimeMessage> {
        let start = Instant::now();

        // Send request / 发送请求
        self.send(request).await?;

        // Wait for response with timeout / 等待响应并处理超时
        let response = tokio::time::timeout(timeout, self.receive())
            .await
            .map_err(|_| CommunicationError::Timeout {
                timeout_ms: timeout.as_millis() as u64,
            })??;

        // Update latency statistics / 更新延迟统计
        let latency = start.elapsed().as_millis() as f64;
        let mut stats = self.stats.write().await;
        stats.avg_latency_ms = (stats.avg_latency_ms + latency) / 2.0;

        Ok(response)
    }

    async fn is_connected(&self) -> bool {
        *self.connected.read().await
    }

    async fn close(&self) -> CommunicationResult<()> {
        // TODO: Implement actual connection closing
        // TODO: 实现实际的连接关闭
        let mut connected = self.connected.write().await;
        *connected = false;
        Ok(())
    }

    async fn get_stats(&self) -> CommunicationResult<ChannelStats> {
        let mut stats = self.stats.read().await.clone();
        stats.uptime_seconds = self.start_time.elapsed().as_secs();
        Ok(stats)
    }
}

/// TCP communication channel
/// TCP 通信通道
pub struct TcpChannel {
    /// Instance identifier for this channel
    /// 此通道的实例标识符
    instance_id: RuntimeInstanceId,
    _config: ChannelConfig,
    stats: Arc<RwLock<ChannelStats>>,
    connected: Arc<RwLock<bool>>,
    start_time: Instant,
}

impl TcpChannel {
    /// Create a new TCP channel
    /// 创建新的 TCP 通道
    pub fn new(instance_id: RuntimeInstanceId, config: ChannelConfig) -> CommunicationResult<Self> {
        Ok(Self {
            instance_id,
            _config: config,
            stats: Arc::new(RwLock::new(ChannelStats::default())),
            connected: Arc::new(RwLock::new(false)),
            start_time: Instant::now(),
        })
    }

    /// Get the instance ID for this channel
    /// 获取此通道的实例ID
    pub fn instance_id(&self) -> &RuntimeInstanceId {
        &self.instance_id
    }

    /// Connect to the TCP endpoint
    /// 连接到 TCP 端点
    pub async fn connect(&self) -> CommunicationResult<()> {
        // TODO: Implement actual TCP connection
        // TODO: 实现实际的 TCP 连接
        let mut connected = self.connected.write().await;
        *connected = true;
        Ok(())
    }
}

#[async_trait]
impl CommunicationChannel for TcpChannel {
    async fn send(&self, _message: RuntimeMessage) -> CommunicationResult<()> {
        if !self.is_connected().await {
            return Err(CommunicationError::ChannelClosed);
        }

        // TODO: Implement actual TCP message sending
        // TODO: 实现实际的 TCP 消息发送

        let mut stats = self.stats.write().await;
        stats.messages_sent += 1;

        Ok(())
    }

    async fn receive(&self) -> CommunicationResult<RuntimeMessage> {
        if !self.is_connected().await {
            return Err(CommunicationError::ChannelClosed);
        }

        // TODO: Implement actual TCP message receiving
        // TODO: 实现实际的 TCP 消息接收

        let mut stats = self.stats.write().await;
        stats.messages_received += 1;

        Ok(RuntimeMessage::Ack {
            request_id: "dummy".to_string(),
        })
    }

    async fn request_response(
        &self,
        request: RuntimeMessage,
        timeout: Duration,
    ) -> CommunicationResult<RuntimeMessage> {
        let start = Instant::now();

        self.send(request).await?;

        let response = tokio::time::timeout(timeout, self.receive())
            .await
            .map_err(|_| CommunicationError::Timeout {
                timeout_ms: timeout.as_millis() as u64,
            })??;

        let latency = start.elapsed().as_millis() as f64;
        let mut stats = self.stats.write().await;
        stats.avg_latency_ms = (stats.avg_latency_ms + latency) / 2.0;

        Ok(response)
    }

    async fn is_connected(&self) -> bool {
        *self.connected.read().await
    }

    async fn close(&self) -> CommunicationResult<()> {
        // TODO: Implement actual TCP connection closing
        // TODO: 实现实际的 TCP 连接关闭
        let mut connected = self.connected.write().await;
        *connected = false;
        Ok(())
    }

    async fn get_stats(&self) -> CommunicationResult<ChannelStats> {
        let mut stats = self.stats.read().await.clone();
        stats.uptime_seconds = self.start_time.elapsed().as_secs();
        Ok(stats)
    }
}

/// gRPC communication channel
/// gRPC 通信通道
pub struct GrpcChannel {
    /// Instance identifier for this channel
    /// 此通道的实例标识符
    instance_id: RuntimeInstanceId,
    _config: ChannelConfig,
    stats: Arc<RwLock<ChannelStats>>,
    connected: Arc<RwLock<bool>>,
    start_time: Instant,
}

impl GrpcChannel {
    /// Create a new gRPC channel
    /// 创建新的 gRPC 通道
    pub fn new(instance_id: RuntimeInstanceId, config: ChannelConfig) -> CommunicationResult<Self> {
        Ok(Self {
            instance_id,
            _config: config,
            stats: Arc::new(RwLock::new(ChannelStats::default())),
            connected: Arc::new(RwLock::new(false)),
            start_time: Instant::now(),
        })
    }

    /// Get the instance ID for this channel
    /// 获取此通道的实例ID
    pub fn instance_id(&self) -> &RuntimeInstanceId {
        &self.instance_id
    }

    /// Connect to the gRPC service
    /// 连接到 gRPC 服务
    pub async fn connect(&self) -> CommunicationResult<()> {
        // TODO: Implement actual gRPC connection
        // TODO: 实现实际的 gRPC 连接
        let mut connected = self.connected.write().await;
        *connected = true;
        Ok(())
    }
}

#[async_trait]
impl CommunicationChannel for GrpcChannel {
    async fn send(&self, _message: RuntimeMessage) -> CommunicationResult<()> {
        if !self.is_connected().await {
            return Err(CommunicationError::ChannelClosed);
        }

        // TODO: Implement actual gRPC message sending
        // TODO: 实现实际的 gRPC 消息发送

        let mut stats = self.stats.write().await;
        stats.messages_sent += 1;

        Ok(())
    }

    async fn receive(&self) -> CommunicationResult<RuntimeMessage> {
        if !self.is_connected().await {
            return Err(CommunicationError::ChannelClosed);
        }

        // TODO: Implement actual gRPC message receiving
        // TODO: 实现实际的 gRPC 消息接收

        let mut stats = self.stats.write().await;
        stats.messages_received += 1;

        Ok(RuntimeMessage::Ack {
            request_id: "dummy".to_string(),
        })
    }

    async fn request_response(
        &self,
        request: RuntimeMessage,
        timeout: Duration,
    ) -> CommunicationResult<RuntimeMessage> {
        let start = Instant::now();

        self.send(request).await?;

        let response = tokio::time::timeout(timeout, self.receive())
            .await
            .map_err(|_| CommunicationError::Timeout {
                timeout_ms: timeout.as_millis() as u64,
            })??;

        let latency = start.elapsed().as_millis() as f64;
        let mut stats = self.stats.write().await;
        stats.avg_latency_ms = (stats.avg_latency_ms + latency) / 2.0;

        Ok(response)
    }

    async fn is_connected(&self) -> bool {
        *self.connected.read().await
    }

    async fn close(&self) -> CommunicationResult<()> {
        // TODO: Implement actual gRPC connection closing
        // TODO: 实现实际的 gRPC 连接关闭
        let mut connected = self.connected.write().await;
        *connected = false;
        Ok(())
    }

    async fn get_stats(&self) -> CommunicationResult<ChannelStats> {
        let mut stats = self.stats.read().await.clone();
        stats.uptime_seconds = self.start_time.elapsed().as_secs();
        Ok(stats)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::spearlet::execution::RuntimeType;

    #[tokio::test]
    async fn test_unix_socket_channel_creation() {
        let instance_id =
            RuntimeInstanceId::new(RuntimeType::Process, "test-unix-instance".to_string());
        let config = ChannelConfig::default();
        let channel = UnixSocketChannel::new(instance_id.clone(), config).unwrap();

        assert_eq!(channel.instance_id(), &instance_id);
        assert!(!channel.is_connected().await);

        let stats = channel.get_stats().await.unwrap();
        assert_eq!(stats.messages_sent, 0);
        assert_eq!(stats.messages_received, 0);
    }

    #[tokio::test]
    async fn test_tcp_channel_creation() {
        let instance_id =
            RuntimeInstanceId::new(RuntimeType::Process, "test-tcp-instance".to_string());
        let config = ChannelConfig {
            instance_id: instance_id.clone(),
            ..Default::default()
        };
        let channel = TcpChannel::new(instance_id.clone(), config).unwrap();

        assert_eq!(channel.instance_id(), &instance_id);
        assert!(!channel.is_connected().await);
    }

    #[tokio::test]
    async fn test_grpc_channel_creation() {
        let instance_id =
            RuntimeInstanceId::new(RuntimeType::Kubernetes, "test-grpc-instance".to_string());
        let config = ChannelConfig {
            instance_id: instance_id.clone(),
            ..Default::default()
        };
        let channel = GrpcChannel::new(instance_id.clone(), config).unwrap();

        assert_eq!(channel.instance_id(), &instance_id);
        assert!(!channel.is_connected().await);
    }

    #[tokio::test]
    async fn test_channel_instance_isolation() {
        let instance1 = RuntimeInstanceId::new(RuntimeType::Process, "instance-1".to_string());
        let instance2 = RuntimeInstanceId::new(RuntimeType::Process, "instance-2".to_string());

        let config1 = ChannelConfig {
            instance_id: instance1.clone(),
            ..Default::default()
        };
        let config2 = ChannelConfig {
            instance_id: instance2.clone(),
            ..Default::default()
        };

        let channel1 = UnixSocketChannel::new(instance1.clone(), config1).unwrap();
        let channel2 = UnixSocketChannel::new(instance2.clone(), config2).unwrap();

        // Channels should have different instance IDs
        // 通道应该有不同的实例ID
        assert_ne!(channel1.instance_id(), channel2.instance_id());
        assert_eq!(channel1.instance_id(), &instance1);
        assert_eq!(channel2.instance_id(), &instance2);
    }
}
