//! 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 StorageManagerCapsule {
    app_data_grant: Grant<AppData>,
}

impl StorageManagerCapsule {
    pub fn new(app_data_grant: Grant<AppData>) -> Self {
        dprintf!("StorageManager::new()");
        return StorageManagerCapsule {
            app_data_grant: app_data_grant,
        };
    }

    pub fn handle_command(
        &self,
        app_data: &mut AppData,
        minor_num: usize,
        arg2: usize,
        arg3: usize,
    ) -> ReturnCode {
        dprintf!(
            "StorageManagerCapsule::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!("StorageManagerCapsule::handle_command : Calling callback!");
                    callback.schedule(1, 2, 3);
                    app_data.callback = Some(callback);
                    ReturnCode::SUCCESS
                } else {
                    dprintf!("StorageManagerCapsule::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!("StorageManagerCapsule::handle_subscribe({})", minor_num);
        if callback.is_some() {
            dprintf!("StorageManagerCapsule::handle_subscribe got Some callback");
        } else {
            dprintf!("StorageManagerCapsule::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!("StorageManagerCapsule::handle_allow({})", slice.len());
            app_data.buffer = Some(slice);
        } else {
            dprintf!("StorageManagerCapsule::handle_allow(None)");
        }
        return ReturnCode::SUCCESS;
    }
}

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

impl Driver for StorageManagerCapsule {
    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())
    }
}
