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

use kernel::{AppId, AppSlice, Callback, Driver, Grant, ReturnCode, Shared};
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 {
        dprintf!("StorageManager::new()\n");
        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())
    }
}
