// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use core::cell::Cell;
use kernel::common::cells::OptionalCell;
use kernel::{AppId, AppSlice, Callback, Driver, Grant, ReturnCode, Shared};
use matcha_config::*;
use matcha_hal::pinmux_hal::PinmuxHAL;

pub struct AppData {
    input_select_callback: Option<Callback>,
    output_select_callback: Option<Callback>,
}

impl Default for AppData {
    fn default() -> AppData {
        AppData {
            input_select_callback: None,
            output_select_callback: None,
        }
    }
}

pub struct PinmuxCapsule {
    pub app_data_grant: Grant<AppData>,
    pub pinmux_hal: OptionalCell<&'static dyn PinmuxHAL>,
    pub current_app: Cell<Option<AppId>>,
}

impl PinmuxCapsule {
    pub fn new(app_data_grant: Grant<AppData>) -> Self {
        PinmuxCapsule {
            app_data_grant: app_data_grant,
            pinmux_hal: OptionalCell::empty(),
            current_app: Cell::new(None),
        }
    }

    pub fn set_pinmux(&self, pinmux: &'static dyn PinmuxHAL) {
        self.pinmux_hal.set(pinmux);
    }

    pub fn handle_command(
        &self,
        app_id: AppId,
        _app_data: &mut AppData,
        minor_num: usize,
        arg2: usize,
        arg3: usize,
    ) -> ReturnCode {
        match minor_num {
            CMD_PINMUX_INIT => {
                self.current_app.set(Some(app_id));
                ReturnCode::SUCCESS
            }
            CMD_PINMUX_INPUT_SELECT => {
                let peripheral: u32 = arg2 as u32;
                let pad: u32 = arg3 as u32;
                let ret = self.pinmux_hal.map_or_else(
                    || { ReturnCode::EINVAL },
                    |pinmux|  {
                        pinmux.input_select(peripheral, pad)
                    }
                );
                self.current_app.get().map(|app_id| {
                    let _ = self.app_data_grant.enter(app_id, |app_data, _| {
                        app_data.input_select_callback.map(|mut callback| {
                            callback.schedule(usize::from(ret), 0, 0);
                        });
                    });
                });
                ret
            }
            CMD_PINMUX_OUTPUT_SELECT => {
                let pad: u32 = arg2 as u32;
                let peripheral: u32 = arg3 as u32;
                let ret = self.pinmux_hal.map_or_else(
                    || { ReturnCode::EINVAL },
                    |pinmux|  {
                        pinmux.output_select(pad, peripheral)
                    }
                );
                self.current_app.get().map(|app_id| {
                    let _ = self.app_data_grant.enter(app_id, |app_data, _| {
                        app_data.output_select_callback.map(|mut callback| {
                            callback.schedule(usize::from(ret), 0, 0);
                        });
                    });
                });
                ret
            }
            _ => 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_PINMUX_INPUT_SELECT => {
                app_data.input_select_callback = callback;
                ReturnCode::SUCCESS
            }
            CMD_PINMUX_OUTPUT_SELECT => {
                app_data.output_select_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_PINMUX_INPUT_SELECT => ReturnCode::SUCCESS,
            CMD_PINMUX_OUTPUT_SELECT => ReturnCode::SUCCESS,
            _ => ReturnCode::EINVAL,
        }
    }
}

impl Driver for PinmuxCapsule {
    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, minor_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, 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_id, app_data, minor_num, slice)
            })
            .unwrap_or_else(|err| err.into())
    }
}