use core::cell::Cell;
use kernel::{AppId, AppSlice, Callback, Driver, Grant, ReturnCode, Shared};
use matcha_hal::dprintf;
use matcha_hal::mailbox_hal::MailboxHAL;

use matcha_config::*;

//------------------------------------------------------------------------------

pub struct AppData {
    pub send_callback: Option<Callback>,
    pub recv_callback: Option<Callback>,
    pub send_buffer: Option<AppSlice<Shared, u8>>,
    pub recv_buffer: Option<AppSlice<Shared, u8>>,
}

impl Default for AppData {
    fn default() -> AppData {
        AppData {
            send_callback: None,
            recv_callback: None,
            send_buffer: None,
            recv_buffer: None,
        }
    }
}

//------------------------------------------------------------------------------
// MailboxCapsule is a global static singleton - its members have to be
// pseudo-const.

pub struct MailboxCapsule {
    pub app_data_grant: Grant<AppData>,
    pub mailbox_hal: Cell<Option<&'static dyn MailboxHAL>>,
    pub current_app: Cell<Option<AppId>>,
}

//----------------------------------------

impl MailboxCapsule {
    pub fn new(app_data_grant: Grant<AppData>) -> Self {
        return MailboxCapsule {
            app_data_grant: app_data_grant,
            mailbox_hal: Cell::new(None),
            current_app: Cell::new(None),
        };
    }

    pub fn set_mailbox(&self, mailbox: &'static dyn MailboxHAL) {
        self.mailbox_hal.set(Some(mailbox));
    }

    pub fn handle_command(
        &self,
        app_id: AppId,
        app_data: &mut AppData,
        cmd_num: usize,
        arg2: usize,
        _arg3: usize,
    ) -> ReturnCode {
        match cmd_num {
            CMD_MAILBOX_INIT => {
                self.current_app.set(Some(app_id));
                ReturnCode::SUCCESS
            }
            CMD_MAILBOX_SEND => {
                let message_len = arg2;
                match &app_data.send_buffer {
                    Some(buffer) => {
                        self.mailbox_hal.get().map(|mb| {
                            let _ = mb.send_message_slice_sync(message_len, buffer);
                        });
                        ReturnCode::SUCCESS
                    }
                    None => ReturnCode::FAIL,
                }
            }
            CMD_MAILBOX_RECV => {
                // Nothing to do here yet?
                ReturnCode::SUCCESS
            }
            _ => {
                dprintf!("MailboxCapsule::handle_command({:?}, ????)\n", app_id);
                ReturnCode::EINVAL
            }
        }
    }

    pub fn handle_subscribe(
        &self,
        _app_id: AppId,
        app_data: &mut AppData,
        minor_num: usize,
        callback: Option<Callback>,
    ) -> ReturnCode {
        match minor_num {
            CMD_MAILBOX_SEND => {
                app_data.send_callback = callback;
                ReturnCode::SUCCESS
            }
            CMD_MAILBOX_RECV => {
                app_data.recv_callback = callback;
                ReturnCode::SUCCESS
            }
            _ => ReturnCode::EINVAL,
        }
    }

    pub fn handle_allow(
        &self,
        _app_id: AppId,
        app_data: &mut AppData,
        minor_num: usize,
        slice: Option<AppSlice<Shared, u8>>,
    ) -> ReturnCode {
        match minor_num {
            CMD_MAILBOX_SEND => {
                app_data.send_buffer = slice;
                ReturnCode::SUCCESS
            }
            CMD_MAILBOX_RECV => {
                app_data.recv_buffer = slice;
                ReturnCode::SUCCESS
            }
            _ => ReturnCode::EINVAL,
        }
    }
}

//------------------------------------------------------------------------------
// Our "driver" trait impl just unwraps the app data grant and delegates to
// MailboxCapsule.

impl Driver for MailboxCapsule {
    fn subscribe(&self, minor_num: usize, callback: Option<Callback>, app_id: AppId) -> ReturnCode {
        self.app_data_grant
            .enter(app_id, |app_data, _| {
                self.handle_subscribe(app_id, app_data, minor_num, callback)
            })
            .unwrap_or_else(|err| err.into())
    }

    fn command(&self, cmd_num: usize, r2: usize, r3: usize, app_id: AppId) -> ReturnCode {
        self.app_data_grant
            .enter(app_id, |app_data, _| {
                self.handle_command(app_id, app_data, cmd_num, r2, r3)
            })
            .unwrap_or_else(|err| err.into())
    }

    fn allow(
        &self,
        app_id: AppId,
        minor_num: usize,
        slice: Option<AppSlice<Shared, u8>>,
    ) -> ReturnCode {
        self.app_data_grant
            .enter(app_id, |app_data, _| {
                self.handle_allow(app_id, app_data, minor_num, slice)
            })
            .unwrap_or_else(|err| err.into())
    }
}

//------------------------------------------------------------------------------

impl matcha_hal::mailbox_hal::MailboxISR for MailboxCapsule {
    fn on_wtirq(&self) {
        // Nothing to do here at the moment, sends are synchronous and the
        // polarity of the ISR is backwards.
    }

    // When a message arrives, we copy it to the waiting app's buffer (if there
    // is one) and then fire the app's callback. Async waiting is handled in
    // app/src/mailbox_client.rs
    fn on_rtirq(&self) {
        // Unwrap all our optionals. There's probably a better way to do this.
        self.current_app.get().map(|app_id| {
            self.app_data_grant.enter(app_id, |app_data, _| {
                app_data.recv_buffer.as_ref().map(|buffer| {
                    self.mailbox_hal.get().map(|mailbox| {
                        // Copy the message to the app's buffer and then
                        // schedule the app callback.
                        match mailbox.get_message_slice_sync(&buffer) {
                            Ok(len) => {
                                let page = mailbox.get_message_page().unwrap_or(0);
                                app_data.recv_callback.map(|mut callback| {
                                    callback.schedule(1, len, page as usize);
                                });
                            }
                            Err(len) => {
                                app_data.recv_callback.map(|mut callback| {
                                    callback.schedule(0, len, 0);
                                });
                            }
                        }
                    });
                });
            })
        });
    }

    fn on_eirq(&self) {
        // We should probably do something here eventually.
    }
}
