//! Module to provide simple ble functions as scanning and advertising

use crate::ble_composer::BlePayload;
use crate::callback::CallbackSubscription;
use crate::callback::Consumer;
use crate::result::TockError;
use crate::result::TockResult;
use crate::shared_memory::SharedMemory;
use crate::syscalls;
use core::cell::Cell;
use core::future::Future;

const DRIVER_NUMBER: usize = 0x30000;
pub const MAX_PAYLOAD_SIZE: usize = 9;
pub const BUFFER_SIZE_ADVERTISE: usize = 39;
pub(crate) const BUFFER_SIZE_SCAN: usize = 39;

mod command_nr {
    pub const START_ADVERTISING: usize = 0;
    pub const PASSIVE_SCAN: usize = 5;
}

mod subscribe_nr {
    pub const BLE_PASSIVE_SCAN_SUB: usize = 0;
}

mod allow_nr {
    pub const ALLOW_ADVERTISMENT_BUFFER: usize = 0;
    pub const ALLOW_SCAN_BUFFER: usize = 1;
}

mod gap_flags {
    pub const BLE_DISCOVERABLE: usize = 0x02;
}

pub mod gap_data {
    pub const COMPLETE_LIST_16BIT_SERVICE_IDS: usize = 0x03;
    pub const COMPLETE_LOCAL_NAME: usize = 0x09;
    pub const SET_FLAGS: usize = 1;
    pub const SERVICE_DATA: usize = 0x16;
}

#[non_exhaustive]
pub struct BleAdvertisingDriverFactory;

impl BleAdvertisingDriverFactory {
    pub fn create_driver(&mut self) -> BleAdvertisingDriver {
        // Unfortunately, there is no way to check the availability of the ble advertising driver
        BleAdvertisingDriver
    }
}

#[non_exhaustive]
pub struct BleAdvertisingDriver;

impl BleAdvertisingDriver {
    pub fn create_advertising_buffer() -> [u8; BUFFER_SIZE_ADVERTISE] {
        [0; BUFFER_SIZE_ADVERTISE]
    }
    pub fn initialize<'a>(
        &'a mut self,
        interval: usize,
        service_payload: &BlePayload,
        advertising_buffer: &'a mut [u8; BUFFER_SIZE_ADVERTISE],
    ) -> TockResult<SharedMemory<'a>> {
        let mut shared_memory = syscalls::allow(
            DRIVER_NUMBER,
            allow_nr::ALLOW_ADVERTISMENT_BUFFER,
            advertising_buffer,
        )?;
        shared_memory.write_bytes(service_payload);
        Self::start_advertising(gap_flags::BLE_DISCOVERABLE, interval)?;
        Ok(shared_memory)
    }

    fn start_advertising(pdu_type: usize, interval: usize) -> TockResult<()> {
        syscalls::command(
            DRIVER_NUMBER,
            command_nr::START_ADVERTISING,
            pdu_type,
            interval,
        )?;
        Ok(())
    }
}

struct BleCallback<'a> {
    read_value: &'a Cell<Option<ScanBuffer>>,
    shared_buffer: SharedMemory<'a>,
}

pub(crate) type ScanBuffer = [u8; BUFFER_SIZE_SCAN];

const EMPTY_SCAN_BUFFER: ScanBuffer = [0; BUFFER_SIZE_SCAN];

#[non_exhaustive]
pub struct BleScanningDriverFactory;

impl BleScanningDriverFactory {
    pub fn create_driver(&mut self) -> BleScanningDriver {
        BleScanningDriver {
            shared_buffer: EMPTY_SCAN_BUFFER,
            read_value: Cell::new(None),
        }
    }
}

/// Uninitialized Ble Scanning Driver
///
/// Usage:
/// ```no_run
/// # use futures::stream::StreamExt;
/// # use libtock::ble_parser;
/// # use libtock::result::TockResult;
/// # use libtock::simple_ble;
/// # async fn doc() -> TockResult<()> {
/// let mut drivers = libtock::retrieve_drivers()?;
/// let led_driver = drivers.leds.init_driver()?;
/// let mut ble_scanning_driver_factory = drivers.ble_scanning;
/// let mut ble_scanning_driver = ble_scanning_driver_factory.create_driver();
/// let mut ble_scanning_driver_sharing = ble_scanning_driver.share_memory()?;
/// let ble_scanning_driver_scanning = ble_scanning_driver_sharing.start()?;
///
/// let value = ble_scanning_driver_scanning.stream_values().await;
/// # Ok(())
/// # }
/// ```
pub struct BleScanningDriver {
    shared_buffer: ScanBuffer,
    read_value: Cell<Option<ScanBuffer>>,
}

impl BleScanningDriver {
    /// Prepare Ble Scanning Driver to share memory with the ble capsule
    pub fn share_memory(&mut self) -> TockResult<BleScanningDriverShared> {
        let shared_buffer: SharedMemory = syscalls::allow(
            DRIVER_NUMBER,
            allow_nr::ALLOW_SCAN_BUFFER,
            &mut self.shared_buffer,
        )
        .map_err(Into::<TockError>::into)?;
        Ok(BleScanningDriverShared {
            read_value: &self.read_value,
            callback: BleCallback {
                read_value: &self.read_value,
                shared_buffer,
            },
        })
    }
}

/// Ble Scanning Driver in "shared buffer" state
pub struct BleScanningDriverShared<'a> {
    callback: BleCallback<'a>,
    read_value: &'a Cell<Option<ScanBuffer>>,
}

impl<'a> BleScanningDriverShared<'a> {
    /// Start scanning for ble advertising events
    pub fn start(&mut self) -> TockResult<BleScanningDriverScanning> {
        let subscription = syscalls::subscribe::<BleCallback<'a>, BleCallback<'a>>(
            DRIVER_NUMBER,
            subscribe_nr::BLE_PASSIVE_SCAN_SUB,
            &mut self.callback,
        )?;
        syscalls::command(DRIVER_NUMBER, command_nr::PASSIVE_SCAN, 1, 0)?;
        Ok(BleScanningDriverScanning {
            _subscription: subscription,
            read_value: self.read_value,
        })
    }
}

/// Ble Scanning Driver in "scanning" state
pub struct BleScanningDriverScanning<'a> {
    _subscription: CallbackSubscription<'a>,
    read_value: &'a Cell<Option<ScanBuffer>>,
}

impl<'a> BleScanningDriverScanning<'a> {
    /// Create stream of ble scanning packets
    pub fn stream_values(&'a self) -> impl Future<Output = ScanBuffer> + 'a {
        crate::futures::wait_for_value(move || {
            if let Some(temp_buffer) = self.read_value.get() {
                self.read_value.set(None);
                Some(temp_buffer)
            } else {
                None
            }
        })
    }
}

impl<'a> Consumer<Self> for BleCallback<'a> {
    fn consume(callback: &mut Self, _: usize, _: usize, _: usize) {
        let mut temporary_buffer: ScanBuffer = EMPTY_SCAN_BUFFER;

        callback.shared_buffer.read_bytes(&mut temporary_buffer[..]);
        callback.read_value.set(Some(temporary_buffer));
    }
}
