// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::server::Facade;
use anyhow::{format_err, Error};
use async_trait::async_trait;
use fidl_fuchsia_bluetooth_gatt::ServiceInfo;
use fidl_fuchsia_bluetooth_le::ScanFilter;
use parking_lot::RwLock;
use serde_json::{to_value, Value};

// Bluetooth-related functionality
use crate::bluetooth::avdtp_facade::AvdtpFacade;
use crate::bluetooth::ble_advertise_facade::BleAdvertiseFacade;
use crate::bluetooth::bt_sys_facade::BluetoothSysFacade;
use crate::bluetooth::facade::BluetoothFacade;
use crate::bluetooth::gatt_client_facade::GattClientFacade;
use crate::bluetooth::gatt_server_facade::GattServerFacade;
use crate::bluetooth::profile_server_facade::ProfileServerFacade;
use crate::bluetooth::types::{
    BleAdvertiseResponse, BleConnectPeripheralResponse, GattcDiscoverCharacteristicResponse,
};

use crate::common_utils::common::{
    parse_identifier, parse_max_bytes, parse_offset, parse_psm, parse_service_identifier,
    parse_u64_identifier, parse_write_value,
};

use crate::common_utils::common::macros::parse_arg;

// Takes a serde_json::Value and converts it to arguments required for a FIDL
// ble_scan command
fn ble_scan_to_fidl(args_raw: Value) -> Result<Option<ScanFilter>, Error> {
    let scan_filter_raw = match args_raw.get("filter") {
        Some(f) => Some(f).unwrap().clone(),
        None => return Err(format_err!("Scan filter missing.")),
    };

    let name_substring: Option<String> =
        scan_filter_raw["name_substring"].as_str().map(String::from);
    // For now, no scan profile, so default to empty ScanFilter
    let filter = Some(ScanFilter {
        service_uuids: None,
        service_data_uuids: None,
        manufacturer_identifier: None,
        connectable: None,
        name_substring: name_substring,
        max_path_loss: None,
    });

    Ok(filter)
}

fn ble_publish_service_to_fidl(args_raw: Value) -> Result<(ServiceInfo, String), Error> {
    let id = parse_arg!(args_raw, as_u64, "id")?;
    let primary = parse_arg!(args_raw, as_bool, "primary")?;
    let type_ = parse_arg!(args_raw, as_str, "type")?;
    let local_service_id = parse_arg!(args_raw, as_str, "local_service_id")?;

    // TODO(fxbug.dev/883): Add support for GATT characterstics and includes
    let characteristics = None;
    let includes = None;

    let service_info =
        ServiceInfo { id, primary, type_: type_.to_string(), characteristics, includes };
    Ok((service_info, local_service_id.to_string()))
}

#[async_trait(?Send)]
impl Facade for BleAdvertiseFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        // TODO(armansito): Once the facade supports multi-advertising it should generate and
        // return a unique ID for each instance. For now we return this dummy ID for the
        // singleton advertisement.
        let id = to_value(BleAdvertiseResponse::new(Some("singleton-instance".to_string())))?;
        match method.as_ref() {
            "BleAdvertise" => {
                self.start_adv(args).await?;
            }
            "BleStopAdvertise" => {
                self.stop_adv();
            }
            _ => return Err(format_err!("Invalid BleAdvertise FIDL method: {:?}", method)),
        };
        Ok(id)
    }

    fn cleanup(&self) {
        Self::cleanup(self)
    }

    fn print(&self) {
        Self::print(self)
    }
}

#[async_trait(?Send)]
impl Facade for RwLock<BluetoothFacade> {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "BlePublishService" => {
                let (service_info, local_service_id) = ble_publish_service_to_fidl(args)?;
                publish_service_async(self, service_info, local_service_id).await
            }
            _ => return Err(format_err!("Invalid BLE FIDL method: {:?}", method)),
        }
    }

    fn cleanup(&self) {
        BluetoothFacade::cleanup(self)
    }

    fn print(&self) {
        self.read().print()
    }
}

#[async_trait(?Send)]
impl Facade for BluetoothSysFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "BluetoothAcceptPairing" => {
                let input = parse_arg!(args, as_str, "input")?;
                let output = parse_arg!(args, as_str, "output")?;
                let result = self.accept_pairing(&input.to_string(), &output.to_string()).await?;
                Ok(to_value(result)?)
            }
            "BluetoothInitSys" => {
                let result = self.init_access_proxy().await?;
                Ok(to_value(result)?)
            }
            "BluetoothGetKnownRemoteDevices" => {
                let result = self.get_known_remote_devices().await?;
                Ok(to_value(result)?)
            }
            "BluetoothSetDiscoverable" => {
                let discoverable = parse_arg!(args, as_bool, "discoverable")?;
                let result = self.set_discoverable(discoverable).await?;
                Ok(to_value(result)?)
            }
            "BluetoothSetName" => {
                let name = parse_arg!(args, as_str, "name")?;
                let result = self.set_name(name.to_string()).await?;
                Ok(to_value(result)?)
            }
            "BluetoothForgetDevice" => {
                let identifier = parse_arg!(args, as_u64, "identifier")?;
                let result = self.forget(identifier).await?;
                Ok(to_value(result)?)
            }
            "BluetoothConnectDevice" => {
                let identifier = parse_arg!(args, as_u64, "identifier")?;
                let result = self.connect(identifier).await?;
                Ok(to_value(result)?)
            }
            "BluetoothDisconnectDevice" => {
                let identifier = parse_arg!(args, as_u64, "identifier")?;
                let result = self.disconnect(identifier).await?;
                Ok(to_value(result)?)
            }
            "BluetoothRequestDiscovery" => {
                let discovery = parse_arg!(args, as_bool, "discovery")?;
                let result = self.start_discovery(discovery).await?;
                Ok(to_value(result)?)
            }
            "BluetoothInputPairingPin" => {
                let pin = parse_arg!(args, as_str, "pin")?;
                let result = self.input_pairing_pin(pin.to_string()).await?;
                Ok(to_value(result)?)
            }
            "BluetoothGetPairingPin" => {
                let result = self.get_pairing_pin().await?;
                Ok(to_value(result)?)
            }
            "BluetoothGetActiveAdapterAddress" => {
                let result = self.get_active_adapter_address().await?;
                Ok(to_value(result)?)
            }
            "BluetoothPairDevice" => {
                let identifier = parse_arg!(args, as_u64, "identifier")?;
                let pairing_security_level =
                    match parse_arg!(args, as_u64, "pairing_security_level") {
                        Ok(v) => Some(v),
                        Err(_e) => None,
                    };
                let non_bondable = match parse_arg!(args, as_bool, "non_bondable") {
                    Ok(v) => Some(v),
                    Err(_e) => None,
                };
                let transport = parse_arg!(args, as_u64, "transport")?;

                let result =
                    self.pair(identifier, pairing_security_level, non_bondable, transport).await?;
                Ok(to_value(result)?)
            }
            _ => bail!("Invalid Bluetooth control FIDL method: {:?}", method),
        }
    }

    fn cleanup(&self) {
        Self::cleanup(self)
    }

    fn print(&self) {
        Self::print(self)
    }
}

#[async_trait(?Send)]
impl Facade for GattClientFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "BleStartScan" => {
                let filter = ble_scan_to_fidl(args)?;
                start_scan_async(&self, filter).await
            }
            "BleStopScan" => stop_scan_async(self).await,
            "BleGetDiscoveredDevices" => le_get_discovered_devices_async(self).await,
            "BleConnectPeripheral" => {
                let id = parse_identifier(args)?;
                connect_peripheral_async(self, id).await
            }
            "BleDisconnectPeripheral" => {
                let id = parse_identifier(args)?;
                disconnect_peripheral_async(self, id).await
            }
            "GattcConnectToService" => {
                let periph_id = parse_identifier(args.clone())?;
                let service_id = parse_service_identifier(args)?;
                gattc_connect_to_service_async(self, periph_id, service_id).await
            }
            "GattcDiscoverCharacteristics" => gattc_discover_characteristics_async(self).await,
            "GattcWriteCharacteristicById" => {
                let id = parse_u64_identifier(args.clone())?;
                let value = parse_write_value(args)?;
                gattc_write_char_by_id_async(self, id, value).await
            }
            "GattcWriteLongCharacteristicById" => {
                let id = parse_u64_identifier(args.clone())?;
                let offset_as_u64 = parse_offset(args.clone())?;
                let offset = offset_as_u64 as u16;
                let value = parse_write_value(args.clone())?;
                let reliable_mode = parse_arg!(args, as_bool, "reliable_mode")?;
                gattc_write_long_char_by_id_async(self, id, offset, value, reliable_mode).await
            }
            "GattcWriteCharacteristicByIdWithoutResponse" => {
                let id = parse_u64_identifier(args.clone())?;
                let value = parse_write_value(args)?;
                gattc_write_char_by_id_without_response_async(self, id, value).await
            }
            "GattcEnableNotifyCharacteristic" => {
                let id = parse_u64_identifier(args.clone())?;
                gattc_toggle_notify_characteristic_async(self, id, true).await
            }
            "GattcDisableNotifyCharacteristic" => {
                let id = parse_u64_identifier(args.clone())?;
                gattc_toggle_notify_characteristic_async(self, id, false).await
            }
            "GattcReadCharacteristicById" => {
                let id = parse_u64_identifier(args.clone())?;
                gattc_read_char_by_id_async(self, id).await
            }
            "GattcReadCharacteristicByType" => {
                let uuid = parse_arg!(args, as_str, "uuid")?;
                let result = self.gattc_read_char_by_type(uuid.to_string()).await?;
                Ok(to_value(result)?)
            }
            "GattcReadLongCharacteristicById" => {
                let id = parse_u64_identifier(args.clone())?;
                let offset_as_u64 = parse_offset(args.clone())?;
                let offset = offset_as_u64 as u16;
                let max_bytes_as_u64 = parse_max_bytes(args)?;
                let max_bytes = max_bytes_as_u64 as u16;
                gattc_read_long_char_by_id_async(self, id, offset, max_bytes).await
            }
            "GattcReadLongDescriptorById" => {
                let id = parse_u64_identifier(args.clone())?;
                let offset_as_u64 = parse_offset(args.clone())?;
                let offset = offset_as_u64 as u16;
                let max_bytes_as_u64 = parse_max_bytes(args)?;
                let max_bytes = max_bytes_as_u64 as u16;
                gattc_read_long_desc_by_id_async(self, id, offset, max_bytes).await
            }
            "GattcWriteDescriptorById" => {
                let id = parse_u64_identifier(args.clone())?;
                let value = parse_write_value(args)?;
                gattc_write_desc_by_id_async(self, id, value).await
            }
            "GattcWriteLongDescriptorById" => {
                let id = parse_u64_identifier(args.clone())?;
                let offset_as_u64 = parse_offset(args.clone())?;
                let offset = offset_as_u64 as u16;
                let value = parse_write_value(args)?;
                gattc_write_long_desc_by_id_async(self, id, offset, value).await
            }
            "GattcReadDescriptorById" => {
                let id = parse_u64_identifier(args.clone())?;
                gattc_read_desc_by_id_async(self, id.clone()).await
            }
            "GattcListServices" => {
                let id = parse_identifier(args)?;
                list_services_async(self, id).await
            }
            _ => return Err(format_err!("Invalid Gatt Client FIDL method: {:?}", method)),
        }
    }

    fn cleanup(&self) {
        Self::cleanup(self)
    }

    fn print(&self) {
        Self::print(self)
    }
}

#[async_trait(?Send)]
impl Facade for GattServerFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "GattServerPublishServer" => {
                let result = self.publish_server(args).await?;
                Ok(to_value(result)?)
            }
            "GattServerCloseServer" => {
                let result = self.close_server().await;
                Ok(to_value(result)?)
            }
            _ => return Err(format_err!("Invalid Gatt Server FIDL method: {:?}", method)),
        }
    }

    fn cleanup(&self) {
        Self::cleanup(self)
    }

    fn print(&self) {
        Self::print(self)
    }
}

#[async_trait(?Send)]
impl Facade for ProfileServerFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "ProfileServerInit" => {
                let result = self.init_profile_server_proxy().await?;
                Ok(to_value(result)?)
            }
            "ProfileServerAddSearch" => {
                let result = self.add_search(args).await?;
                Ok(to_value(result)?)
            }
            "ProfileServerAddService" => {
                let result = self.add_service(args).await?;
                Ok(to_value(result)?)
            }
            "ProfileServerCleanup" => {
                let result = self.cleanup().await?;
                Ok(to_value(result)?)
            }
            "ProfileServerConnectL2cap" => {
                let id = parse_identifier(args.clone())?;
                let psm = parse_psm(args.clone())?;
                let mode = parse_arg!(args, as_str, "mode")?;
                let result = self.connect(id, psm as u16, &mode.to_string()).await?;
                Ok(to_value(result)?)
            }
            "ProfileServerRemoveService" => {
                let service_id = parse_u64_identifier(args)? as usize;
                let result = self.remove_service(service_id).await?;
                Ok(to_value(result)?)
            }
            _ => return Err(format_err!("Invalid Profile Server FIDL method: {:?}", method)),
        }
    }
}

#[async_trait(?Send)]
impl Facade for AvdtpFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "AvdtpInit" => {
                let role = parse_arg!(args, as_str, "role")?;
                let result = self.init_avdtp_service_proxy(role.to_string()).await?;
                Ok(to_value(result)?)
            }
            "AvdtpGetConnectedPeers" => {
                let result = self.get_connected_peers().await?;
                Ok(to_value(result)?)
            }
            "AvdtpSetConfiguration" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.set_configuration(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpGetConfiguration" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.get_configuration(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpGetCapabilities" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.get_capabilities(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpGetAllCapabilities" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.get_all_capabilities(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpReconfigureStream" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.reconfigure_stream(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpSuspendStream" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.suspend_stream(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpSuspendAndReconfigure" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.suspend_and_reconfigure(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpReleaseStream" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.release_stream(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpEstablishStream" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.establish_stream(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpStartStream" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.start_stream(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpAbortStream" => {
                let peer_id = parse_u64_identifier(args)?;
                let result = self.abort_stream(peer_id).await?;
                Ok(to_value(result)?)
            }
            "AvdtpRemoveService" => {
                let result = self.remove_service().await;
                Ok(to_value(result)?)
            }
            _ => bail!("Invalid AVDTP FIDL method: {:?}", method),
        }
    }
}

async fn start_scan_async(
    facade: &GattClientFacade,
    filter: Option<ScanFilter>,
) -> Result<Value, Error> {
    let start_scan_result = facade.start_scan(filter).await?;
    Ok(to_value(start_scan_result)?)
}

async fn stop_scan_async(facade: &GattClientFacade) -> Result<Value, Error> {
    let central = facade.get_central_proxy().clone().expect("No central proxy.");
    if let Err(e) = central.stop_scan() {
        return Err(format_err!("Error stopping scan: {}", e));
    } else {
        // Get the list of devices discovered by the scan.
        let devices = facade.get_devices();
        match to_value(devices) {
            Ok(dev) => Ok(dev),
            Err(e) => Err(e.into()),
        }
    }
}

async fn le_get_discovered_devices_async(facade: &GattClientFacade) -> Result<Value, Error> {
    // Get the list of devices discovered by the scan.
    match to_value(facade.get_devices()) {
        Ok(dev) => Ok(dev),
        Err(e) => Err(e.into()),
    }
}

async fn connect_peripheral_async(facade: &GattClientFacade, id: String) -> Result<Value, Error> {
    let connect_periph_result = facade.connect_peripheral(id).await?;
    Ok(to_value(connect_periph_result)?)
}

async fn disconnect_peripheral_async(
    facade: &GattClientFacade,
    id: String,
) -> Result<Value, Error> {
    let value = facade.disconnect_peripheral(id).await?;
    Ok(to_value(value)?)
}

// Uses the same return type as connect_peripheral_async -- Returns subset of
// fidl::ServiceInfo
async fn list_services_async(facade: &GattClientFacade, id: String) -> Result<Value, Error> {
    let list_services_result = facade.list_services(id).await?;
    Ok(to_value(BleConnectPeripheralResponse::new(list_services_result))?)
}

async fn gattc_connect_to_service_async(
    facade: &GattClientFacade,
    periph_id: String,
    service_id: u64,
) -> Result<Value, Error> {
    let connect_to_service_result = facade.gattc_connect_to_service(periph_id, service_id).await?;
    Ok(to_value(connect_to_service_result)?)
}

async fn gattc_discover_characteristics_async(facade: &GattClientFacade) -> Result<Value, Error> {
    let discover_characteristics_results = facade.gattc_discover_characteristics().await?;
    Ok(to_value(GattcDiscoverCharacteristicResponse::new(discover_characteristics_results))?)
}

async fn gattc_write_char_by_id_async(
    facade: &GattClientFacade,
    id: u64,
    write_value: Vec<u8>,
) -> Result<Value, Error> {
    let write_char_status = facade.gattc_write_char_by_id(id, write_value).await?;
    Ok(to_value(write_char_status)?)
}

async fn gattc_write_long_char_by_id_async(
    facade: &GattClientFacade,
    id: u64,
    offset: u16,
    write_value: Vec<u8>,
    reliable_mode: bool,
) -> Result<Value, Error> {
    let write_char_status =
        facade.gattc_write_long_char_by_id(id, offset, write_value, reliable_mode).await?;
    Ok(to_value(write_char_status)?)
}

async fn gattc_write_char_by_id_without_response_async(
    facade: &GattClientFacade,
    id: u64,
    write_value: Vec<u8>,
) -> Result<Value, Error> {
    let write_char_status = facade.gattc_write_char_by_id_without_response(id, write_value).await?;
    Ok(to_value(write_char_status)?)
}

async fn gattc_read_char_by_id_async(facade: &GattClientFacade, id: u64) -> Result<Value, Error> {
    let read_char_status = facade.gattc_read_char_by_id(id).await?;
    Ok(to_value(read_char_status)?)
}

async fn gattc_read_long_char_by_id_async(
    facade: &GattClientFacade,
    id: u64,
    offset: u16,
    max_bytes: u16,
) -> Result<Value, Error> {
    let read_long_char_status = facade.gattc_read_long_char_by_id(id, offset, max_bytes).await?;
    Ok(to_value(read_long_char_status)?)
}

async fn gattc_read_long_desc_by_id_async(
    facade: &GattClientFacade,
    id: u64,
    offset: u16,
    max_bytes: u16,
) -> Result<Value, Error> {
    let read_long_desc_status = facade.gattc_read_long_desc_by_id(id, offset, max_bytes).await?;
    Ok(to_value(read_long_desc_status)?)
}

async fn gattc_read_desc_by_id_async(facade: &GattClientFacade, id: u64) -> Result<Value, Error> {
    let read_desc_status = facade.gattc_read_desc_by_id(id).await?;
    Ok(to_value(read_desc_status)?)
}

async fn gattc_write_desc_by_id_async(
    facade: &GattClientFacade,
    id: u64,
    write_value: Vec<u8>,
) -> Result<Value, Error> {
    let write_desc_status = facade.gattc_write_desc_by_id(id, write_value).await?;
    Ok(to_value(write_desc_status)?)
}

async fn gattc_write_long_desc_by_id_async(
    facade: &GattClientFacade,
    id: u64,
    offset: u16,
    write_value: Vec<u8>,
) -> Result<Value, Error> {
    let write_desc_status = facade.gattc_write_long_desc_by_id(id, offset, write_value).await?;
    Ok(to_value(write_desc_status)?)
}

async fn gattc_toggle_notify_characteristic_async(
    facade: &GattClientFacade,
    id: u64,
    value: bool,
) -> Result<Value, Error> {
    let toggle_notify_result = facade.gattc_toggle_notify_characteristic(id, value).await?;
    Ok(to_value(toggle_notify_result)?)
}

async fn publish_service_async(
    facade: &RwLock<BluetoothFacade>,
    service_info: ServiceInfo,
    local_service_id: String,
) -> Result<Value, Error> {
    let publish_service_result =
        BluetoothFacade::publish_service(&facade, service_info, local_service_id).await?;
    Ok(to_value(publish_service_result)?)
}
