//! [TSM.ID].[11031972] — Platform X Ecosystem
//! Channel implementations for IPC

use crate::{IpcError, Result};
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};

pub struct SharedMemoryChannel {
    buffer: Arc<Mutex<VecDeque<Vec<u8>>>>,
    capacity: usize,
    name: String,
    closed: Arc<Mutex<bool>>,
}

impl SharedMemoryChannel {
    pub fn new(name: &str, capacity: usize) -> Self {
        Self {
            buffer: Arc::new(Mutex::new(VecDeque::with_capacity(capacity))),
            capacity, name: name.to_string(),
            closed: Arc::new(Mutex::new(false)),
        }
    }

    pub fn send(&self, data: Vec<u8>) -> Result<()> {
        let closed = self.closed.lock().map_err(|e| IpcError::LockPoisoned(e.to_string()))?;
        if *closed { return Err(IpcError::ChannelClosed); }
        drop(closed);
        let mut buf = self.buffer.lock().map_err(|e| IpcError::LockPoisoned(e.to_string()))?;
        if buf.len() >= self.capacity { return Err(IpcError::BufferFull); }
        buf.push_back(data);
        Ok(())
    }

    pub fn recv(&self) -> Result<Option<Vec<u8>>> {
        let mut buf = self.buffer.lock().map_err(|e| IpcError::LockPoisoned(e.to_string()))?;
        Ok(buf.pop_front())
    }

    pub fn close(&self) -> Result<()> {
        let mut c = self.closed.lock().map_err(|e| IpcError::LockPoisoned(e.to_string()))?;
        *c = true;
        Ok(())
    }

    pub fn name(&self) -> &str { &self.name }
    pub fn len(&self) -> usize { self.buffer.lock().map(|b| b.len()).unwrap_or(0) }
    pub fn is_empty(&self) -> bool { self.len() == 0 }
}
