use crate::memory_manager::{CoreMemory, MemoryStorable};
use anyhow::{Result, bail, ensure};


#[derive(Debug, Clone)]
pub struct Crossbar {
    max_width: usize,
    max_height: usize,
    stored_bytes: usize,
    memory: CoreMemory,
}

impl Crossbar {
    pub fn new(width: usize, height: usize, memory: CoreMemory) -> Self {
        Self { max_width: width, max_height: height, memory, stored_bytes:0 }
    }

    pub fn width(&self) -> usize {
        self.max_width
    }

    pub fn height(&self) -> usize {
        self.max_height
    }

    pub fn stored_bytes(&self) -> usize {
        self.stored_bytes
    }

    pub fn execute_store<T>(&mut self, element: &[T]) -> Result<()> where
            T: MemoryStorable, {
        self.memory.clear();
        let total_size = self.max_width * self.max_height;
        self.memory.set_capacity(total_size);
        let stored_size = std::mem::size_of_val(element);
        ensure!(stored_size <= total_size, "Storing more than crossbar can handle");
        self.stored_bytes=stored_size;
        self.memory.execute_store(0, element)
    }

    pub fn load<T>(&mut self, size: usize) -> Result<Vec<&[T]>> where
            T: MemoryStorable, {
        if self.memory.get_len() <  size 
            //|| self.stored_bytes < size 
        {
            bail!("Loading outside crossbar boundary [{} {}] <  {}", self.stored_bytes, self.memory.get_len() ,  size);
        }
        self.memory.load(0, size)
    }



}
