// 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 bt_rfcomm::ServerChannel;
use fidl_fuchsia_bluetooth::PeerId;
use fidl_fuchsia_bluetooth_a2dp::Role;
use fidl_fuchsia_bluetooth_hfp::{CallDirection, CallState, NetworkInformation, SignalStrength};
use fidl_fuchsia_bluetooth_le::Filter;
use fidl_fuchsia_bluetooth_sys::{LeSecurityMode, Settings};
use serde_json::{from_value, to_value, Value};
use test_call_manager::TestCallManager as HfpFacade;
use test_rfcomm_client::RfcommManager as RfcommFacade;

// Bluetooth-related functionality
use crate::bluetooth::a2dp_facade::A2dpFacade;
use crate::bluetooth::avdtp_facade::AvdtpFacade;
use crate::bluetooth::avrcp_facade::AvrcpFacade;
use crate::bluetooth::ble_advertise_facade::BleAdvertiseFacade;
use crate::bluetooth::bt_sys_facade::BluetoothSysFacade;
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::{
    AbsoluteVolumeCommand, BleAdvertiseResponse, BleConnectPeripheralResponse, CustomBatteryStatus,
    CustomNotificationsFilter, CustomPlayerApplicationSettings,
    CustomPlayerApplicationSettingsAttributeIds, FacadeArg, GattcDiscoverCharacteristicResponse,
};

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

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

#[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 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_identifier_as_u64(&args)?;
                let result = self.forget(identifier).await?;
                Ok(to_value(result)?)
            }
            "BluetoothConnectDevice" => {
                let identifier = parse_identifier_as_u64(&args)?;
                let result = self.connect(identifier).await?;
                Ok(to_value(result)?)
            }
            "BluetoothDisconnectDevice" => {
                let identifier = parse_identifier_as_u64(&args)?;
                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_identifier_as_u64(&args)?;
                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)?)
            }
            "BluetoothUpdateSystemSettings" => {
                let le_privacy = parse_arg!(args, as_bool, "le_privacy").ok();
                let le_background_scan = parse_arg!(args, as_bool, "le_background_scan").ok();
                let bredr_connectable_mode =
                    parse_arg!(args, as_bool, "bredr_connectable_mode").ok();
                let le_security_mode = if let Ok(s) = parse_arg!(args, as_str, "le_security_mode") {
                    match s.to_uppercase().as_ref() {
                        "MODE_1" => Some(LeSecurityMode::Mode1),
                        "SECURE_CONNECTIONS_ONLY" => Some(LeSecurityMode::SecureConnectionsOnly),
                        _ => bail!(
                            "Invalid le_security_mode {} passed to BluetoothUpdateSystemSettings",
                            s
                        ),
                    }
                } else {
                    None
                };
                let result = self
                    .update_settings(Settings {
                        le_privacy,
                        le_background_scan,
                        bredr_connectable_mode,
                        le_security_mode,
                        ..Default::default()
                    })
                    .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 scan_filter = FacadeArg::new(args);
                start_scan_async(&self, Some(scan_filter.try_into()?)).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 initiator_delay = match parse_arg!(args, as_str, "initiator_delay") {
                    Ok(v) => Some(v.to_string()),
                    Err(_e) => None,
                };
                let result = self.init_avdtp_service_proxy(initiator_delay).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_trait(?Send)]
impl Facade for A2dpFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "A2dpSetRole" => {
                let a2dp_role = if let Ok(s) = parse_arg!(args, as_str, "a2dp_role") {
                    match s.to_uppercase().as_ref() {
                        "SOURCE" => Role::Source,
                        "SINK" => Role::Sink,
                        _ => bail!("Invalid A2DP role {} passed to A2dpSetRole", s),
                    }
                } else {
                    bail!("Could not parse A2DP role passed to A2dpSetRole")
                };

                self.init_audio_mode_proxy().await?;
                let result = self.set_role(a2dp_role).await?;
                Ok(to_value(result)?)
            }

            _ => {
                bail!("Invalid A2DP FIDL method: {:?}", method)
            }
        }
    }
}

#[async_trait(?Send)]
impl Facade for AvrcpFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "AvrcpInit" => {
                let target_id = parse_arg!(args, as_str, "target_id")?;
                let target_id = target_id.parse::<u64>()?;
                let result = self.init_avrcp(target_id).await?;
                Ok(to_value(result)?)
            }
            "AvrcpGetMediaAttributes" => {
                let result = self.get_media_attributes().await?;
                Ok(to_value(result)?)
            }
            "AvrcpGetPlayStatus" => {
                let result = self.get_play_status().await?;
                Ok(to_value(result)?)
            }
            "AvrcpGetPlayerApplicationSettings" => {
                let attribute_ids: CustomPlayerApplicationSettingsAttributeIds =
                    match from_value(args.clone()) {
                        Ok(attribute_ids) => attribute_ids,
                        _ => bail!(
                            "Invalid json argument to AvrcpGetPlayerApplicationSettings! - {}",
                            args
                        ),
                    };
                let result = self.get_player_application_settings(attribute_ids.clone()).await?;
                Ok(to_value(result)?)
            }
            "AvrcpInformBatteryStatus" => {
                let battery_status: CustomBatteryStatus = match from_value(args.clone()) {
                    Ok(battery_status) => battery_status,
                    _ => bail!("Invalid json argument to AvrcpInformBatteryStatus! - {}", args),
                };
                let result = self.inform_battery_status(battery_status.clone()).await?;
                Ok(to_value(result)?)
            }
            "AvrcpNotifyNotificationHandled" => {
                let result = self.notify_notification_handled().await?;
                Ok(to_value(result)?)
            }
            "AvrcpSetAddressedPlayer" => {
                let player_id: u16 = match from_value(args.clone()) {
                    Ok(settings) => settings,
                    _ => bail!("Invalid json argument to AvrcpSetAddressedPlayer! - {}", args),
                };
                let result = self.set_addressed_player(player_id.clone()).await?;
                Ok(to_value(result)?)
            }
            "AvrcpSetPlayerApplicationSettings" => {
                let settings: CustomPlayerApplicationSettings = match from_value(args.clone()) {
                    Ok(settings) => settings,
                    _ => bail!(
                        "Invalid json argument to AvrcpSetPlayerApplicationSettings! - {}",
                        args
                    ),
                };
                let result = self.set_player_application_settings(settings.clone()).await?;
                Ok(to_value(result)?)
            }
            "AvrcpSendCommand" => {
                let command_str = parse_arg!(args, as_str, "command")?;
                let result = self.send_command(command_str.to_string().into()).await?;
                Ok(to_value(result)?)
            }
            "AvrcpSetAbsoluteVolume" => {
                let absolute_volume_command: AbsoluteVolumeCommand = match from_value(args.clone())
                {
                    Ok(absolute_volume) => absolute_volume,
                    _ => bail!("Invalid json argument to AvrcpSetAbsoluteVolume! - {}", args),
                };
                let result =
                    self.set_absolute_volume(absolute_volume_command.absolute_volume).await?;
                Ok(to_value(result)?)
            }
            "AvrcpSetNotificationFilter" => {
                let custom_notifications: CustomNotificationsFilter = match from_value(args.clone())
                {
                    Ok(custom_notifications) => custom_notifications,
                    _ => bail!("Invalid json argument to AvrcpSetNotificationFilter! - {}", args),
                };
                let result = self
                    .set_notification_filter(
                        custom_notifications.notifications,
                        match custom_notifications.position_change_interval {
                            Some(position_change_interval) => position_change_interval,
                            _ => 0,
                        },
                    )
                    .await?;
                Ok(to_value(result)?)
            }
            _ => bail!("Invalid AVRCP FIDL method: {:?}", method),
        }
    }

    fn cleanup(&self) {}

    fn print(&self) {}
}

async fn start_scan_async(
    facade: &GattClientFacade,
    filter: Option<Filter>,
) -> 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> {
    facade.stop_scan().await?;
    // Get the list of devices discovered by the scan.
    let devices = facade.get_scan_responses();
    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_scan_responses()) {
        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_trait(?Send)]
impl Facade for HfpFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "HfpInit" => {
                let result = self.init_hfp_service().await?;
                Ok(to_value(result)?)
            }
            "HfpRemoveService" => {
                self.cleanup().await;
                Ok(to_value(())?)
            }
            "ListPeers" => {
                let result = self.list_peers().await?;
                Ok(to_value(result)?)
            }
            "SetActivePeer" => {
                let id = parse_arg!(args, as_u64, "peer_id")?;
                let result = self.set_active_peer(id).await?;
                Ok(to_value(result)?)
            }
            "ListCalls" => {
                let result = self.list_calls().await?;
                Ok(to_value(result)?)
            }
            "NewCall" => {
                let remote = parse_arg!(args, as_str, "remote")?;
                let state = parse_arg!(args, as_str, "state")?.to_lowercase();
                let state = match &*state {
                    "ringing" => CallState::IncomingRinging,
                    "waiting" => CallState::IncomingWaiting,
                    "dialing" => CallState::OutgoingDialing,
                    "alerting" => CallState::OutgoingAlerting,
                    "active" => CallState::OngoingActive,
                    "held" => CallState::OngoingHeld,
                    _ => bail!("Invalid state argument: {}", state),
                };
                let direction = parse_arg!(args, as_str, "direction")?;
                let direction = match &*direction {
                    "incoming" => CallDirection::MobileTerminated,
                    "outgoing" => CallDirection::MobileOriginated,
                    _ => bail!("Invalid direction argument: {}", direction),
                };
                let result = self.new_call(&remote, state, direction).await?;
                Ok(to_value(result)?)
            }
            "IncomingCall" => {
                let remote = parse_arg!(args, as_str, "remote")?;
                let result = self.incoming_ringing_call(&remote).await?;
                Ok(to_value(result)?)
            }
            "IncomingWaitingCall" => {
                let remote = parse_arg!(args, as_str, "remote")?;
                let result = self.incoming_waiting_call(&remote).await?;
                Ok(to_value(result)?)
            }
            "OutgoingCall" => {
                let remote = parse_arg!(args, as_str, "remote")?;
                let result = self.outgoing_call(&remote).await?;
                Ok(to_value(result)?)
            }
            "SetCallActive" => {
                let call_id = parse_arg!(args, as_u64, "call_id")?;
                let result = self.set_call_active(call_id).await?;
                Ok(to_value(result)?)
            }
            "SetCallHeld" => {
                let call_id = parse_arg!(args, as_u64, "call_id")?;
                let result = self.set_call_held(call_id).await?;
                Ok(to_value(result)?)
            }
            "SetCallTerminated" => {
                let call_id = parse_arg!(args, as_u64, "call_id")?;
                let result = self.set_call_terminated(call_id).await?;
                Ok(to_value(result)?)
            }
            "SetCallTransferredToAg" => {
                let call_id = parse_arg!(args, as_u64, "call_id")?;
                let result = self.set_call_transferred_to_ag(call_id).await?;
                Ok(to_value(result)?)
            }
            "SetSpeakerGain" => {
                let value = parse_arg!(args, as_u64, "value")?;
                let result = self.set_speaker_gain(value).await?;
                Ok(to_value(result)?)
            }
            "SetMicrophoneGain" => {
                let value = parse_arg!(args, as_u64, "value")?;
                let result = self.set_microphone_gain(value).await?;
                Ok(to_value(result)?)
            }
            "SetServiceAvailable" => {
                let service_available = Some(parse_arg!(args, as_bool, "value")?);
                let result = self
                    .update_network_information(NetworkInformation {
                        service_available,
                        ..Default::default()
                    })
                    .await?;
                Ok(to_value(result)?)
            }
            "SetRoaming" => {
                let roaming = Some(parse_arg!(args, as_bool, "value")?);
                let result = self
                    .update_network_information(NetworkInformation {
                        roaming,
                        ..Default::default()
                    })
                    .await?;
                Ok(to_value(result)?)
            }
            "SetSignalStrength" => {
                let signal_strength = parse_arg!(args, as_u64, "value")?;
                let signal_strength = Some(match signal_strength {
                    0 => SignalStrength::None,
                    1 => SignalStrength::VeryLow,
                    2 => SignalStrength::Low,
                    3 => SignalStrength::Medium,
                    4 => SignalStrength::High,
                    5 => SignalStrength::VeryHigh,
                    _ => panic!(""),
                });
                let result = self
                    .update_network_information(NetworkInformation {
                        signal_strength,
                        ..Default::default()
                    })
                    .await?;
                Ok(to_value(result)?)
            }
            "SetSubscriberNumber" => {
                let number = parse_arg!(args, as_str, "value")?;
                self.set_subscriber_number(number).await;
                Ok(to_value(())?)
            }
            "SetOperator" => {
                let value = parse_arg!(args, as_str, "value")?;
                self.set_operator(value).await;
                Ok(to_value(())?)
            }
            "SetNrecSupport" => {
                let support = parse_arg!(args, as_bool, "value")?;
                self.set_nrec_support(support).await;
                Ok(to_value(())?)
            }
            "SetBatteryLevel" => {
                let level = parse_arg!(args, as_u64, "value")?;
                self.set_battery_level(level).await?;
                Ok(to_value(())?)
            }
            "SetLastDialed" => {
                let number = parse_arg!(args, as_str, "number")?.to_string();
                self.set_last_dialed(Some(number)).await;
                Ok(to_value(())?)
            }
            "ClearLastDialed" => {
                self.set_last_dialed(None).await;
                Ok(to_value(())?)
            }
            "SetMemoryLocation" => {
                let location = parse_arg!(args, as_str, "location")?.to_string();
                let number = parse_arg!(args, as_str, "number")?.to_string();
                self.set_memory_location(location, Some(number)).await;
                Ok(to_value(())?)
            }
            "ClearMemoryLocation" => {
                let location = parse_arg!(args, as_str, "location")?.to_string();
                self.set_memory_location(location, None).await;
                Ok(to_value(())?)
            }
            "SetDialResult" => {
                let number = parse_arg!(args, as_str, "number")?.to_string();
                let status = parse_arg!(args, as_i64, "status")?.try_into()?;
                let status = fuchsia_zircon::Status::from_raw(status);
                self.set_dial_result(number, status).await;
                Ok(to_value(())?)
            }
            "GetState" => {
                let result = self.get_state().await;
                Ok(to_value(result)?)
            }
            "SetConnectionBehavior" => {
                let autoconnect = parse_arg!(args, as_bool, "autoconnect")?;
                self.set_connection_behavior(autoconnect).await?;
                Ok(to_value(())?)
            }
            _ => bail!("Invalid Hfp FIDL method: {:?}", method),
        }
    }
}

#[async_trait(?Send)]
impl Facade for RfcommFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match method.as_ref() {
            "RfcommInit" => {
                let result = self.advertise()?;
                Ok(to_value(result)?)
            }
            "RfcommRemoveService" => {
                let result = self.clear_services();
                Ok(to_value(result)?)
            }
            "DisconnectSession" => {
                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
                let result = self.close_session(id.into())?;
                Ok(to_value(result)?)
            }
            "ConnectRfcommChannel" => {
                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
                let channel_number = parse_arg!(args, as_u64, "server_channel_number")?;
                let channel_number = ServerChannel::try_from(u8::try_from(channel_number)?)?;
                let result = self.outgoing_rfcomm_channel(id.into(), channel_number).await?;
                Ok(to_value(result)?)
            }
            "DisconnectRfcommChannel" => {
                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
                let channel_number = parse_arg!(args, as_u64, "server_channel_number")?;
                let channel_number = ServerChannel::try_from(u8::try_from(channel_number)?)?;
                let result = self.close_rfcomm_channel(id.into(), channel_number)?;
                Ok(to_value(result)?)
            }
            "SendRemoteLineStatus" => {
                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
                let channel_number = parse_arg!(args, as_u64, "server_channel_number")?;
                let channel_number = ServerChannel::try_from(u8::try_from(channel_number)?)?;
                let result = self.send_rls(id.into(), channel_number)?;
                Ok(to_value(result)?)
            }
            "RfcommWrite" => {
                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
                let channel_number = parse_arg!(args, as_u64, "server_channel_number")?;
                let channel_number = ServerChannel::try_from(u8::try_from(channel_number)?)?;
                let data = parse_arg!(args, as_str, "data")?.to_string();
                let result = self.send_user_data(id.into(), channel_number, data.into_bytes())?;
                Ok(to_value(result)?)
            }
            _ => bail!("Invalid RFCOMM method: {:?}", method),
        }
    }
}
