//! Stub StorageManager capsule that doesn't do anything yet.

use kernel::{AppId, AppSlice, Callback, Driver, Grant, ReturnCode, Shared};
// TODO(sleffler): remove dprintf noise once this code does something
use matcha_hal::dprintf;

#[derive(Default)]
pub struct AppData {
    pub callback: Option<Callback>,
    pub buffer: Option<AppSlice<Shared, u8>>,
    pub minor_num: usize,
    pub arg2: usize,
    pub arg3: usize,
}

pub struct StorageCapsule {
    app_data_grant: Grant<AppData>,
}

impl StorageCapsule {
    pub fn new(app_data_grant: Grant<AppData>) -> Self {
        return StorageCapsule {
            app_data_grant: app_data_grant,
        };
    }

    pub fn handle_command(
        &self,
        app_data: &mut AppData,
        minor_num: usize,
        arg2: usize,
        arg3: usize,
    ) -> ReturnCode {
        dprintf!(
            "StorageCapsule::handle_command({}, {}, {})",
            minor_num,
            arg2,
            arg3
        );
        app_data.minor_num = minor_num;
        app_data.arg2 = arg2;
        app_data.arg3 = arg3;
        match minor_num {
            0 => ReturnCode::SUCCESS,
            1 => {
                if let Some(mut callback) = app_data.callback {
                    dprintf!("StorageCapsule::handle_command : Calling callback!");
                    callback.schedule(1, 2, 3);
                    app_data.callback = Some(callback);
                    ReturnCode::SUCCESS
                } else {
                    dprintf!("StorageCapsule::handle_command : No callback!");
                    ReturnCode::EINVAL
                }
            }
            _ => ReturnCode::EINVAL,
        }
    }

    pub fn handle_subscribe(
        &self,
        app_data: &mut AppData,
        minor_num: usize,
        callback: Option<Callback>,
    ) -> ReturnCode {
        dprintf!("StorageCapsule::handle_subscribe({})", minor_num);
        if callback.is_some() {
            dprintf!("StorageCapsule::handle_subscribe got Some callback");
        } else {
            dprintf!("StorageCapsule::handle_subscribe got None callback");
        }
        app_data.callback = callback;
        return ReturnCode::SUCCESS;
    }

    pub fn handle_allow(
        &self,
        app_data: &mut AppData,
        _minor_num: usize,
        slice: Option<AppSlice<Shared, u8>>,
    ) -> ReturnCode {
        if let Some(slice) = slice {
            dprintf!("StorageCapsule::handle_allow({})", slice.len());
            app_data.buffer = Some(slice);
        } else {
            dprintf!("StorageCapsule::handle_allow(None)");
        }
        return ReturnCode::SUCCESS;
    }
}

/// Driver impl just enters the app_data grant and delegates to StorageCapsule.

impl Driver for StorageCapsule {
    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_data, minor_num, callback)
            })
            .unwrap_or_else(|err| err.into())
    }

    fn command(&self, minor_num: usize, r2: usize, r3: usize, app_id: AppId) -> ReturnCode {
        self.app_data_grant
            .enter(app_id, |app_data, _| {
                self.handle_command(app_data, minor_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_data, minor_num, slice)
            })
            .unwrap_or_else(|err| err.into())
    }
}
