//! the system interface

use {
    crate::ipc::message::Message,
    crossbeam_queue::{ArrayQueue, SegQueue},
    hbvm::engine::Engine,
    log::trace,
};
/// Host errors
pub enum HostError {
    /// A host memory error
    MemoryError,
}

/// Check f0 register  for the handle
/// check f1 for the message ptr
/// check f2 for the message length
pub fn ipc_send(engine: &mut Engine) -> Result<(), HostError> {
    let _handle = engine.registers.f0;
    let message_start = engine.registers.f1;
    let message_length = engine.registers.f2;

    let mut ipc_msg: alloc::vec::Vec<u8> = alloc::vec![];

    for x in message_start..message_start + message_length {
        let byte = engine.read_mem_addr_8(x);
        match byte {
            Ok(byte) => ipc_msg.push(byte),
            Err(_) => return Err(HostError::MemoryError),
        }
    }
    log::trace!("Message bytes {:?}", ipc_msg);
    Ok(())
}

// pub fn ipc_recv(_engine: &mut Engine) {}

/// Check f0 for the buffer type
/// 0 means an unbound buffer
/// 1 means a bound buffer
/// Check f1 if the buffer is bound
///
/// f2 Return a handle to the sender
/// f3 returns a handle the the reciever
pub fn ipc_mkbuf(engine: &mut Engine) {
    match engine.registers.f0 as usize {
        0 => {
            trace!("Making a new ipc unbound buffer");
            let _buf: SegQueue<Message> = SegQueue::new();
        }
        1 => {
            let buf_len = engine.registers.f1 as usize;
            trace!("Making a new ipc buffer with capacity {}", buf_len);
            let _buf: ArrayQueue<Message> = ArrayQueue::new(buf_len);
        }
        _ => {}
    }
}

// pub fn rpc_discover(_engine: &mut Engine) {}
// pub fn rpc_register(_engine: &mut Engine) {}
// pub fn rpc_call(_engine: &mut Engine) {}