//! [TSM.ID].[11031972] — Platform X Ecosystem
//! xcu-webview-bridge — Native OS to WebView interface bridge
#![deny(warnings)]
#![allow(dead_code)]

pub mod bridge;
pub mod platform;

use serde::{Serialize, Deserialize};
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum Platform {
    Android,
    Ios,
    HarmonyOs,
    Desktop,
    WebAssembly,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BridgeMessage {
    pub id: u64,
    pub source: Platform,
    pub target: String,
    pub payload: String,
    pub timestamp_ms: u64,
}

#[derive(Debug)]
pub enum BridgeError {
    SerializationFailed(String),
    QueueFull,
    InvalidTarget(String),
    PlatformNotSupported(Platform),
    Timeout,
}

impl std::fmt::Display for BridgeError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::SerializationFailed(e) => write!(f, "Serialization failed: {e}"),
            Self::QueueFull => write!(f, "Message queue is full"),
            Self::InvalidTarget(t) => write!(f, "Invalid target: {t}"),
            Self::PlatformNotSupported(p) => write!(f, "Platform not supported: {p:?}"),
            Self::Timeout => write!(f, "Bridge operation timed out"),
        }
    }
}

impl std::error::Error for BridgeError {}

pub type Result<T> = std::result::Result<T, BridgeError>;

pub struct MessageQueue {
    queue: Arc<Mutex<VecDeque<BridgeMessage>>>,
    capacity: usize,
    counter: Arc<Mutex<u64>>,
}

impl MessageQueue {
    pub fn new(capacity: usize) -> Self {
        Self {
            queue: Arc::new(Mutex::new(VecDeque::with_capacity(capacity))),
            capacity,
            counter: Arc::new(Mutex::new(0)),
        }
    }

    pub fn enqueue(&self, mut msg: BridgeMessage) -> Result<u64> {
        let mut q = self.queue.lock().map_err(|e| BridgeError::SerializationFailed(e.to_string()))?;
        if q.len() >= self.capacity {
            return Err(BridgeError::QueueFull);
        }
        let mut c = self.counter.lock().map_err(|e| BridgeError::SerializationFailed(e.to_string()))?;
        *c += 1;
        msg.id = *c;
        let id = msg.id;
        q.push_back(msg);
        Ok(id)
    }

    pub fn dequeue(&self) -> Result<Option<BridgeMessage>> {
        let mut q = self.queue.lock().map_err(|e| BridgeError::SerializationFailed(e.to_string()))?;
        Ok(q.pop_front())
    }

    pub fn len(&self) -> usize {
        self.queue.lock().map(|q| q.len()).unwrap_or(0)
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }
}

pub trait WebViewBridge {
    fn send(&self, msg: BridgeMessage) -> Result<u64>;
    fn receive(&self) -> Result<Option<BridgeMessage>>;
    fn eval_js(&self, script: &str) -> Result<String>;
    fn platform(&self) -> Platform;
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_message_queue() {
        let q = MessageQueue::new(10);
        let msg = BridgeMessage {
            id: 0, source: Platform::Android,
            target: "ui".into(), payload: "hello".into(), timestamp_ms: 100,
        };
        let id = q.enqueue(msg).unwrap();
        assert_eq!(id, 1);
        assert!(!q.is_empty());
        let out = q.dequeue().unwrap().unwrap();
        assert_eq!(out.payload, "hello");
    }
}
