//! Anything related to the GATT API (IBluetoothGatt).

use btif_macros::{btif_callback, btif_callbacks_dispatcher};

use bt_topshim::bindings::root::bluetooth::Uuid;
use bt_topshim::btif::{BluetoothInterface, RawAddress, Uuid128Bit};
use bt_topshim::profiles::gatt::{
    BtGattDbElement, BtGattNotifyParams, BtGattReadParams, Gatt, GattClientCallbacks,
    GattClientCallbacksDispatcher, GattServerCallbacksDispatcher, GattStatus,
};
use bt_topshim::topstack;

use log::{debug, warn};
use num_traits::cast::{FromPrimitive, ToPrimitive};
use std::collections::HashSet;
use std::sync::{Arc, Mutex};
use tokio::sync::mpsc::Sender;

use crate::{Message, RPCProxy};

struct Client {
    id: Option<i32>,
    uuid: Uuid128Bit,
    callback: Box<dyn IBluetoothGattCallback + Send>,
    is_congested: bool,

    // Queued on_characteristic_write callback.
    congestion_queue: Vec<(String, i32, i32)>,
}

struct Connection {
    conn_id: i32,
    address: String,
    client_id: i32,
}

struct ContextMap {
    // TODO(b/196635530): Consider using `multimap` for a more efficient implementation of get by
    // multiple keys.
    clients: Vec<Client>,
    connections: Vec<Connection>,
}

impl ContextMap {
    fn new() -> ContextMap {
        ContextMap { clients: vec![], connections: vec![] }
    }

    fn get_by_uuid(&self, uuid: &Uuid128Bit) -> Option<&Client> {
        self.clients.iter().find(|client| client.uuid == *uuid)
    }

    fn get_by_client_id(&self, client_id: i32) -> Option<&Client> {
        self.clients.iter().find(|client| client.id.is_some() && client.id.unwrap() == client_id)
    }

    fn get_by_client_id_mut(&mut self, client_id: i32) -> Option<&mut Client> {
        self.clients
            .iter_mut()
            .find(|client| client.id.is_some() && client.id.unwrap() == client_id)
    }

    fn get_address_by_conn_id(&self, conn_id: i32) -> Option<String> {
        match self.connections.iter().find(|conn| conn.conn_id == conn_id) {
            None => None,
            Some(conn) => Some(conn.address.clone()),
        }
    }

    fn get_client_by_conn_id(&self, conn_id: i32) -> Option<&Client> {
        match self.connections.iter().find(|conn| conn.conn_id == conn_id) {
            None => None,
            Some(conn) => self.get_by_client_id(conn.client_id),
        }
    }

    fn get_client_by_conn_id_mut(&mut self, conn_id: i32) -> Option<&mut Client> {
        let client_id = match self.connections.iter().find(|conn| conn.conn_id == conn_id) {
            None => return None,
            Some(conn) => conn.client_id,
        };

        self.get_by_client_id_mut(client_id)
    }

    fn add(&mut self, uuid: &Uuid128Bit, callback: Box<dyn IBluetoothGattCallback + Send>) {
        if self.get_by_uuid(uuid).is_some() {
            return;
        }

        self.clients.push(Client {
            id: None,
            uuid: uuid.clone(),
            callback,
            is_congested: false,
            congestion_queue: vec![],
        });
    }

    fn remove(&mut self, id: i32) {
        self.clients.retain(|client| !(client.id.is_some() && client.id.unwrap() == id));
    }

    fn set_client_id(&mut self, uuid: &Uuid128Bit, id: i32) {
        let client = self.clients.iter_mut().find(|client| client.uuid == *uuid);
        if client.is_none() {
            return;
        }

        client.unwrap().id = Some(id);
    }

    fn add_connection(&mut self, client_id: i32, conn_id: i32, address: &String) {
        if self.get_conn_id_from_address(client_id, address).is_some() {
            return;
        }

        self.connections.push(Connection { conn_id, address: address.clone(), client_id });
    }

    fn remove_connection(&mut self, _client_id: i32, conn_id: i32) {
        self.connections.retain(|conn| conn.conn_id != conn_id);
    }

    fn get_conn_id_from_address(&self, client_id: i32, address: &String) -> Option<i32> {
        match self
            .connections
            .iter()
            .find(|conn| conn.client_id == client_id && conn.address == *address)
        {
            None => None,
            Some(conn) => Some(conn.conn_id),
        }
    }
}

/// Defines the GATT API.
pub trait IBluetoothGatt {
    fn register_scanner(&self, callback: Box<dyn IScannerCallback + Send>);

    fn unregister_scanner(&self, scanner_id: i32);

    fn start_scan(&self, scanner_id: i32, settings: ScanSettings, filters: Vec<ScanFilter>);
    fn stop_scan(&self, scanner_id: i32);

    /// Registers a GATT Client.
    fn register_client(
        &mut self,
        app_uuid: String,
        callback: Box<dyn IBluetoothGattCallback + Send>,
        eatt_support: bool,
    );

    /// Unregisters a GATT Client.
    fn unregister_client(&mut self, client_id: i32);

    /// Initiates a GATT connection to a peer device.
    fn client_connect(
        &self,
        client_id: i32,
        addr: String,
        is_direct: bool,
        transport: i32,
        opportunistic: bool,
        phy: i32,
    );

    /// Disconnects a GATT connection.
    fn client_disconnect(&self, client_id: i32, addr: String);

    /// Sets preferred PHY.
    fn client_set_preferred_phy(
        &self,
        client_id: i32,
        addr: String,
        tx_phy: LePhy,
        rx_phy: LePhy,
        phy_options: i32,
    );

    /// Reads the PHY used by a peer.
    fn client_read_phy(&mut self, client_id: i32, addr: String);

    /// Clears the attribute cache of a device.
    fn refresh_device(&self, client_id: i32, addr: String);

    /// Enumerates all GATT services on a connected device.
    fn discover_services(&self, client_id: i32, addr: String);

    /// Search a GATT service on a connected device based on a UUID.
    fn discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String);

    /// Reads a characteristic on a remote device.
    fn read_characteristic(&self, client_id: i32, addr: String, handle: i32, auth_req: i32);

    /// Reads a characteristic on a remote device.
    fn read_using_characteristic_uuid(
        &self,
        client_id: i32,
        addr: String,
        uuid: String,
        start_handle: i32,
        end_handle: i32,
        auth_req: i32,
    );

    /// Writes a remote characteristic.
    fn write_characteristic(
        &self,
        client_id: i32,
        addr: String,
        handle: i32,
        write_type: GattWriteType,
        auth_req: i32,
        value: Vec<u8>,
    ) -> GattWriteRequestStatus;

    /// Reads the descriptor for a given characteristic.
    fn read_descriptor(&self, client_id: i32, addr: String, handle: i32, auth_req: i32);

    /// Writes a remote descriptor for a given characteristic.
    fn write_descriptor(
        &self,
        client_id: i32,
        addr: String,
        handle: i32,
        auth_req: i32,
        value: Vec<u8>,
    );

    /// Registers to receive notifications or indications for a given characteristic.
    fn register_for_notification(&self, client_id: i32, addr: String, handle: i32, enable: bool);

    /// Begins reliable write.
    fn begin_reliable_write(&mut self, client_id: i32, addr: String);

    /// Ends reliable write.
    fn end_reliable_write(&mut self, client_id: i32, addr: String, execute: bool);

    /// Requests RSSI for a given remote device.
    fn read_remote_rssi(&self, client_id: i32, addr: String);

    /// Configures the MTU of a given connection.
    fn configure_mtu(&self, client_id: i32, addr: String, mtu: i32);

    /// Requests a connection parameter update.
    fn connection_parameter_update(
        &self,
        client_id: i32,
        addr: String,
        min_interval: i32,
        max_interval: i32,
        latency: i32,
        timeout: i32,
        min_ce_len: u16,
        max_ce_len: u16,
    );
}

#[derive(Debug, Default)]
/// Represents a GATT Descriptor.
pub struct BluetoothGattDescriptor {
    pub uuid: Uuid128Bit,
    pub instance_id: i32,
    pub permissions: i32,
}

impl BluetoothGattDescriptor {
    fn new(uuid: Uuid128Bit, instance_id: i32, permissions: i32) -> BluetoothGattDescriptor {
        BluetoothGattDescriptor { uuid, instance_id, permissions }
    }
}

#[derive(Debug, Default)]
/// Represents a GATT Characteristic.
pub struct BluetoothGattCharacteristic {
    pub uuid: Uuid128Bit,
    pub instance_id: i32,
    pub properties: i32,
    pub permissions: i32,
    pub key_size: i32,
    pub write_type: GattWriteType,
    pub descriptors: Vec<BluetoothGattDescriptor>,
}

impl BluetoothGattCharacteristic {
    pub const PROPERTY_BROADCAST: i32 = 0x01;
    pub const PROPERTY_READ: i32 = 0x02;
    pub const PROPERTY_WRITE_NO_RESPONSE: i32 = 0x04;
    pub const PROPERTY_WRITE: i32 = 0x08;
    pub const PROPERTY_NOTIFY: i32 = 0x10;
    pub const PROPERTY_INDICATE: i32 = 0x20;
    pub const PROPERTY_SIGNED_WRITE: i32 = 0x40;
    pub const PROPERTY_EXTENDED_PROPS: i32 = 0x80;

    fn new(
        uuid: Uuid128Bit,
        instance_id: i32,
        properties: i32,
        permissions: i32,
    ) -> BluetoothGattCharacteristic {
        BluetoothGattCharacteristic {
            uuid,
            instance_id,
            properties,
            permissions,
            write_type: if properties & BluetoothGattCharacteristic::PROPERTY_WRITE_NO_RESPONSE != 0
            {
                GattWriteType::WriteNoRsp
            } else {
                GattWriteType::Write
            },
            key_size: 16,
            descriptors: vec![],
        }
    }
}

#[derive(Debug, Default)]
/// Represents a GATT Service.
pub struct BluetoothGattService {
    pub uuid: Uuid128Bit,
    pub instance_id: i32,
    pub service_type: i32,
    pub characteristics: Vec<BluetoothGattCharacteristic>,
    pub included_services: Vec<BluetoothGattService>,
}

impl BluetoothGattService {
    fn new(uuid: Uuid128Bit, instance_id: i32, service_type: i32) -> BluetoothGattService {
        BluetoothGattService {
            uuid,
            instance_id,
            service_type,
            characteristics: vec![],
            included_services: vec![],
        }
    }
}

/// Callback for GATT Client API.
pub trait IBluetoothGattCallback: RPCProxy {
    /// When the `register_client` request is done.
    fn on_client_registered(&self, status: i32, client_id: i32);

    /// When there is a change in the state of a GATT client connection.
    fn on_client_connection_state(
        &self,
        status: i32,
        client_id: i32,
        connected: bool,
        addr: String,
    );

    /// When there is a change of PHY.
    fn on_phy_update(&self, addr: String, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus);

    /// The completion of IBluetoothGatt::read_phy.
    fn on_phy_read(&self, addr: String, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus);

    /// When GATT db is available.
    fn on_search_complete(&self, addr: String, services: Vec<BluetoothGattService>, status: i32);

    /// The completion of IBluetoothGatt::read_characteristic.
    fn on_characteristic_read(&self, addr: String, status: i32, handle: i32, value: Vec<u8>);

    /// The completion of IBluetoothGatt::write_characteristic.
    fn on_characteristic_write(&self, addr: String, status: i32, handle: i32);

    /// When a reliable write is completed.
    fn on_execute_write(&self, addr: String, status: i32);

    /// The completion of IBluetoothGatt::read_descriptor.
    fn on_descriptor_read(&self, addr: String, status: i32, handle: i32, value: Vec<u8>);

    /// The completion of IBluetoothGatt::write_descriptor.
    fn on_descriptor_write(&self, addr: String, status: i32, handle: i32);

    /// When notification or indication is received.
    fn on_notify(&self, addr: String, handle: i32, value: Vec<u8>);

    /// The completion of IBluetoothGatt::read_remote_rssi.
    fn on_read_remote_rssi(&self, addr: String, rssi: i32, status: i32);

    /// The completion of IBluetoothGatt::configure_mtu.
    fn on_configure_mtu(&self, addr: String, mtu: i32, status: i32);

    /// When a connection parameter changes.
    fn on_connection_updated(
        &self,
        addr: String,
        interval: i32,
        latency: i32,
        timeout: i32,
        status: i32,
    );

    /// When there is an addition, removal, or change of a GATT service.
    fn on_service_changed(&self, addr: String);
}

/// Interface for scanner callbacks to clients, passed to `IBluetoothGatt::register_scanner`.
pub trait IScannerCallback {
    /// When the `register_scanner` request is done.
    fn on_scanner_registered(&self, status: i32, scanner_id: i32);
}

#[derive(Debug, FromPrimitive, ToPrimitive)]
#[repr(u8)]
/// GATT write type.
enum GattDbElementType {
    PrimaryService = 0,
    SecondaryService = 1,
    IncludedService = 2,
    Characteristic = 3,
    Descriptor = 4,
}

#[derive(Debug, FromPrimitive, ToPrimitive)]
#[repr(u8)]
/// GATT write type.
pub enum GattWriteType {
    Invalid = 0,
    WriteNoRsp = 1,
    Write = 2,
    WritePrepare = 3,
}

impl Default for GattWriteType {
    fn default() -> Self {
        GattWriteType::Write
    }
}

#[derive(Debug, FromPrimitive, ToPrimitive)]
#[repr(u8)]
/// Represents LE PHY.
pub enum LePhy {
    Invalid = 0,
    Phy1m = 1,
    Phy2m = 2,
    PhyCoded = 3,
}

#[derive(Debug, FromPrimitive, ToPrimitive)]
#[repr(u32)]
/// Scan type configuration.
pub enum ScanType {
    Active = 0,
    Passive = 1,
}

impl Default for ScanType {
    fn default() -> Self {
        ScanType::Active
    }
}

/// Represents RSSI configurations for hardware offloaded scanning.
// TODO(b/200066804): This is still a placeholder struct, not yet complete.
#[derive(Debug, Default)]
pub struct RSSISettings {
    pub low_threshold: i32,
    pub high_threshold: i32,
}

/// Represents scanning configurations to be passed to `IBluetoothGatt::start_scan`.
#[derive(Debug, Default)]
pub struct ScanSettings {
    pub interval: i32,
    pub window: i32,
    pub scan_type: ScanType,
    pub rssi_settings: RSSISettings,
}

/// Represents a scan filter to be passed to `IBluetoothGatt::start_scan`.
#[derive(Debug, Default)]
pub struct ScanFilter {}

/// Implementation of the GATT API (IBluetoothGatt).
pub struct BluetoothGatt {
    intf: Arc<Mutex<BluetoothInterface>>,
    gatt: Option<Gatt>,

    context_map: ContextMap,
    reliable_queue: HashSet<String>,
}

impl BluetoothGatt {
    /// Constructs a new IBluetoothGatt implementation.
    pub fn new(intf: Arc<Mutex<BluetoothInterface>>) -> BluetoothGatt {
        BluetoothGatt {
            intf: intf,
            gatt: None,
            context_map: ContextMap::new(),
            reliable_queue: HashSet::new(),
        }
    }

    pub fn init_profiles(&mut self, tx: Sender<Message>) {
        self.gatt = Gatt::new(&self.intf.lock().unwrap());
        self.gatt.as_mut().unwrap().initialize(
            GattClientCallbacksDispatcher {
                dispatch: Box::new(move |cb| {
                    let tx_clone = tx.clone();
                    topstack::get_runtime().spawn(async move {
                        let _ = tx_clone.send(Message::GattClient(cb)).await;
                    });
                }),
            },
            GattServerCallbacksDispatcher {
                dispatch: Box::new(move |cb| {
                    // TODO(b/193685149): Implement the callbacks
                    debug!("received Gatt server callback: {:?}", cb);
                }),
            },
        );
    }
}

// Temporary util that covers only basic string conversion.
// TODO(b/193685325): Implement more UUID utils by using Uuid from gd/hci/uuid.h with cxx.
fn parse_uuid_string<T: Into<String>>(uuid: T) -> Option<Uuid> {
    let uuid = uuid.into();

    if uuid.len() != 32 {
        return None;
    }

    let mut raw = [0; 16];

    for i in 0..16 {
        let byte = u8::from_str_radix(&uuid[i * 2..i * 2 + 2], 16);
        if byte.is_err() {
            return None;
        }
        raw[i] = byte.unwrap();
    }

    Some(Uuid { uu: raw })
}

#[derive(Debug, FromPrimitive, ToPrimitive)]
#[repr(u8)]
/// Status of WriteCharacteristic methods.
pub enum GattWriteRequestStatus {
    Success = 0,
    Fail = 1,
    Busy = 2,
}

impl IBluetoothGatt for BluetoothGatt {
    fn register_scanner(&self, _callback: Box<dyn IScannerCallback + Send>) {
        // TODO(b/200066804): implement
    }

    fn unregister_scanner(&self, _scanner_id: i32) {
        // TODO(b/200066804): implement
    }

    fn start_scan(&self, _scanner_id: i32, _settings: ScanSettings, _filters: Vec<ScanFilter>) {
        // TODO(b/200066804): implement
    }

    fn stop_scan(&self, _scanner_id: i32) {
        // TODO(b/200066804): implement
    }

    fn register_client(
        &mut self,
        app_uuid: String,
        callback: Box<dyn IBluetoothGattCallback + Send>,
        eatt_support: bool,
    ) {
        let uuid = parse_uuid_string(app_uuid).unwrap();
        self.context_map.add(&uuid.uu, callback);
        self.gatt.as_ref().unwrap().client.register_client(&uuid, eatt_support);
    }

    fn unregister_client(&mut self, client_id: i32) {
        self.context_map.remove(client_id);
        self.gatt.as_ref().unwrap().client.unregister_client(client_id);
    }

    fn client_connect(
        &self,
        client_id: i32,
        addr: String,
        is_direct: bool,
        transport: i32,
        opportunistic: bool,
        phy: i32,
    ) {
        let address = match RawAddress::from_string(addr.clone()) {
            None => return,
            Some(addr) => addr,
        };

        self.gatt.as_ref().unwrap().client.connect(
            client_id,
            &address,
            is_direct,
            transport,
            opportunistic,
            phy,
        );
    }

    fn client_disconnect(&self, client_id: i32, address: String) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &address);
        if conn_id.is_none() {
            return;
        }

        self.gatt.as_ref().unwrap().client.disconnect(
            client_id,
            &RawAddress::from_string(address).unwrap(),
            conn_id.unwrap(),
        );
    }

    fn client_set_preferred_phy(
        &self,
        client_id: i32,
        address: String,
        tx_phy: LePhy,
        rx_phy: LePhy,
        phy_options: i32,
    ) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &address);
        if conn_id.is_none() {
            return;
        }

        self.gatt.as_ref().unwrap().client.set_preferred_phy(
            &RawAddress::from_string(address).unwrap(),
            tx_phy.to_u8().unwrap(),
            rx_phy.to_u8().unwrap(),
            phy_options as u16,
        );
    }

    fn client_read_phy(&mut self, client_id: i32, addr: String) {
        let address = match RawAddress::from_string(addr.clone()) {
            None => return,
            Some(addr) => addr,
        };

        self.gatt.as_mut().unwrap().client.read_phy(client_id, &address);
    }

    fn refresh_device(&self, client_id: i32, addr: String) {
        self.gatt
            .as_ref()
            .unwrap()
            .client
            .refresh(client_id, &RawAddress::from_string(addr).unwrap());
    }

    fn discover_services(&self, client_id: i32, addr: String) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return;
        }

        self.gatt.as_ref().unwrap().client.search_service(conn_id.unwrap(), None);
    }

    fn discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return;
        }

        let uuid = parse_uuid_string(uuid);
        if uuid.is_none() {
            return;
        }

        self.gatt.as_ref().unwrap().client.search_service(conn_id.unwrap(), uuid);
    }

    fn read_characteristic(&self, client_id: i32, addr: String, handle: i32, auth_req: i32) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return;
        }

        // TODO(b/200065274): Perform check on restricted handles.

        self.gatt.as_ref().unwrap().client.read_characteristic(
            conn_id.unwrap(),
            handle as u16,
            auth_req,
        );
    }

    fn read_using_characteristic_uuid(
        &self,
        client_id: i32,
        addr: String,
        uuid: String,
        start_handle: i32,
        end_handle: i32,
        auth_req: i32,
    ) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return;
        }

        let uuid = parse_uuid_string(uuid);
        if uuid.is_none() {
            return;
        }

        // TODO(b/200065274): Perform check on restricted handles.

        self.gatt.as_ref().unwrap().client.read_using_characteristic_uuid(
            conn_id.unwrap(),
            &uuid.unwrap(),
            start_handle as u16,
            end_handle as u16,
            auth_req,
        );
    }

    fn write_characteristic(
        &self,
        client_id: i32,
        addr: String,
        handle: i32,
        mut write_type: GattWriteType,
        auth_req: i32,
        value: Vec<u8>,
    ) -> GattWriteRequestStatus {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return GattWriteRequestStatus::Fail;
        }

        if self.reliable_queue.contains(&addr) {
            write_type = GattWriteType::WritePrepare;
        }

        // TODO(b/200065274): Perform check on restricted handles.

        // TODO(b/200070162): Handle concurrent write characteristic.

        self.gatt.as_ref().unwrap().client.write_characteristic(
            conn_id.unwrap(),
            handle as u16,
            write_type.to_i32().unwrap(),
            auth_req,
            &value,
        );

        return GattWriteRequestStatus::Success;
    }

    fn read_descriptor(&self, client_id: i32, addr: String, handle: i32, auth_req: i32) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return;
        }

        // TODO(b/200065274): Perform check on restricted handles.

        self.gatt.as_ref().unwrap().client.read_descriptor(
            conn_id.unwrap(),
            handle as u16,
            auth_req,
        );
    }

    fn write_descriptor(
        &self,
        client_id: i32,
        addr: String,
        handle: i32,
        auth_req: i32,
        value: Vec<u8>,
    ) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return;
        }

        // TODO(b/200065274): Perform check on restricted handles.

        self.gatt.as_ref().unwrap().client.write_descriptor(
            conn_id.unwrap(),
            handle as u16,
            auth_req,
            &value,
        );
    }

    fn register_for_notification(&self, client_id: i32, addr: String, handle: i32, enable: bool) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return;
        }

        // TODO(b/200065274): Perform check on restricted handles.

        if enable {
            self.gatt.as_ref().unwrap().client.register_for_notification(
                client_id,
                &RawAddress::from_string(addr).unwrap(),
                handle as u16,
            );
        } else {
            self.gatt.as_ref().unwrap().client.deregister_for_notification(
                client_id,
                &RawAddress::from_string(addr).unwrap(),
                handle as u16,
            );
        }
    }

    fn begin_reliable_write(&mut self, _client_id: i32, addr: String) {
        self.reliable_queue.insert(addr);
    }

    fn end_reliable_write(&mut self, client_id: i32, addr: String, execute: bool) {
        self.reliable_queue.remove(&addr);

        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return;
        }

        self.gatt
            .as_ref()
            .unwrap()
            .client
            .execute_write(conn_id.unwrap(), if execute { 1 } else { 0 });
    }

    fn read_remote_rssi(&self, client_id: i32, addr: String) {
        self.gatt
            .as_ref()
            .unwrap()
            .client
            .read_remote_rssi(client_id, &RawAddress::from_string(addr).unwrap());
    }

    fn configure_mtu(&self, client_id: i32, addr: String, mtu: i32) {
        let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr);
        if conn_id.is_none() {
            return;
        }

        self.gatt.as_ref().unwrap().client.configure_mtu(conn_id.unwrap(), mtu);
    }

    fn connection_parameter_update(
        &self,
        _client_id: i32,
        addr: String,
        min_interval: i32,
        max_interval: i32,
        latency: i32,
        timeout: i32,
        min_ce_len: u16,
        max_ce_len: u16,
    ) {
        self.gatt.as_ref().unwrap().client.conn_parameter_update(
            &RawAddress::from_string(addr).unwrap(),
            min_interval,
            max_interval,
            latency,
            timeout,
            min_ce_len,
            max_ce_len,
        );
    }
}

#[btif_callbacks_dispatcher(BluetoothGatt, dispatch_gatt_client_callbacks, GattClientCallbacks)]
pub(crate) trait BtifGattClientCallbacks {
    #[btif_callback(RegisterClient)]
    fn register_client_cb(&mut self, status: i32, client_id: i32, app_uuid: Uuid);

    #[btif_callback(Connect)]
    fn connect_cb(&mut self, conn_id: i32, status: i32, client_id: i32, addr: RawAddress);

    #[btif_callback(Disconnect)]
    fn disconnect_cb(&mut self, conn_id: i32, status: i32, client_id: i32, addr: RawAddress);

    #[btif_callback(SearchComplete)]
    fn search_complete_cb(&mut self, conn_id: i32, status: i32);

    #[btif_callback(RegisterForNotification)]
    fn register_for_notification_cb(
        &mut self,
        conn_id: i32,
        registered: i32,
        status: i32,
        handle: u16,
    );

    #[btif_callback(Notify)]
    fn notify_cb(&mut self, conn_id: i32, data: BtGattNotifyParams);

    #[btif_callback(ReadCharacteristic)]
    fn read_characteristic_cb(&mut self, conn_id: i32, status: i32, data: BtGattReadParams);

    #[btif_callback(WriteCharacteristic)]
    fn write_characteristic_cb(&mut self, conn_id: i32, status: i32, handle: u16);

    #[btif_callback(ReadDescriptor)]
    fn read_descriptor_cb(&mut self, conn_id: i32, status: i32, data: BtGattReadParams);

    #[btif_callback(WriteDescriptor)]
    fn write_descriptor_cb(&mut self, conn_id: i32, status: i32, handle: u16);

    #[btif_callback(ExecuteWrite)]
    fn execute_write_cb(&mut self, conn_id: i32, status: i32);

    #[btif_callback(ReadRemoteRssi)]
    fn read_remote_rssi_cb(&mut self, client_id: i32, addr: RawAddress, rssi: i32, status: i32);

    #[btif_callback(ConfigureMtu)]
    fn configure_mtu_cb(&mut self, conn_id: i32, status: i32, mtu: i32);

    #[btif_callback(Congestion)]
    fn congestion_cb(&mut self, conn_id: i32, congested: bool);

    #[btif_callback(GetGattDb)]
    fn get_gatt_db_cb(&mut self, conn_id: i32, elements: Vec<BtGattDbElement>, count: i32);

    #[btif_callback(PhyUpdated)]
    fn phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: u8);

    #[btif_callback(ConnUpdated)]
    fn conn_updated_cb(
        &mut self,
        conn_id: i32,
        interval: u16,
        latency: u16,
        timeout: u16,
        status: u8,
    );

    #[btif_callback(ServiceChanged)]
    fn service_changed_cb(&self, conn_id: i32);

    #[btif_callback(ReadPhy)]
    fn read_phy_cb(&mut self, client_id: i32, addr: RawAddress, tx_phy: u8, rx_phy: u8, status: u8);
}

impl BtifGattClientCallbacks for BluetoothGatt {
    fn register_client_cb(&mut self, status: i32, client_id: i32, app_uuid: Uuid) {
        self.context_map.set_client_id(&app_uuid.uu, client_id);

        let client = self.context_map.get_by_uuid(&app_uuid.uu);
        if client.is_none() {
            warn!("Warning: Client not registered for UUID {:?}", app_uuid.uu);
            return;
        }

        let callback = &client.unwrap().callback;
        callback.on_client_registered(status, client_id);
    }

    fn connect_cb(&mut self, conn_id: i32, status: i32, client_id: i32, addr: RawAddress) {
        if status == 0 {
            self.context_map.add_connection(client_id, conn_id, &addr.to_string());
        }

        let client = self.context_map.get_by_client_id(client_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_client_connection_state(
            status,
            client_id,
            match GattStatus::from_i32(status) {
                None => false,
                Some(gatt_status) => gatt_status == GattStatus::Success,
            },
            addr.to_string(),
        );
    }

    fn disconnect_cb(&mut self, conn_id: i32, status: i32, client_id: i32, addr: RawAddress) {
        self.context_map.remove_connection(client_id, conn_id);
        let client = self.context_map.get_by_client_id(client_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_client_connection_state(
            status,
            client_id,
            match GattStatus::from_i32(status) {
                None => false,
                Some(gatt_status) => gatt_status == GattStatus::Success,
            },
            addr.to_string(),
        );
    }

    fn search_complete_cb(&mut self, conn_id: i32, _status: i32) {
        // Gatt DB is ready!
        self.gatt.as_ref().unwrap().client.get_gatt_db(conn_id);
    }

    fn register_for_notification_cb(
        &mut self,
        _conn_id: i32,
        _registered: i32,
        _status: i32,
        _handle: u16,
    ) {
        // No-op.
    }

    fn notify_cb(&mut self, conn_id: i32, data: BtGattNotifyParams) {
        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_notify(
            RawAddress { val: data.bda.address }.to_string(),
            data.handle as i32,
            data.value[0..data.len as usize].to_vec(),
        );
    }

    fn read_characteristic_cb(&mut self, conn_id: i32, status: i32, data: BtGattReadParams) {
        let address = self.context_map.get_address_by_conn_id(conn_id);
        if address.is_none() {
            return;
        }

        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_characteristic_read(
            address.unwrap().to_string(),
            status,
            data.handle as i32,
            data.value.value[0..data.value.len as usize].to_vec(),
        );
    }

    fn write_characteristic_cb(&mut self, conn_id: i32, mut status: i32, handle: u16) {
        let address = self.context_map.get_address_by_conn_id(conn_id);
        if address.is_none() {
            return;
        }

        // TODO(b/200070162): Design how to handle concurrent write characteristic to the same
        // peer.

        let client = self.context_map.get_client_by_conn_id_mut(conn_id);
        if client.is_none() {
            return;
        }

        let client = client.unwrap();

        if client.is_congested {
            if status == GattStatus::Congested.to_i32().unwrap() {
                status = GattStatus::Success.to_i32().unwrap();
            }

            client.congestion_queue.push((address.unwrap().to_string(), status, handle as i32));
            return;
        }

        client.callback.on_characteristic_write(
            address.unwrap().to_string(),
            status,
            handle as i32,
        );
    }

    fn read_descriptor_cb(&mut self, conn_id: i32, status: i32, data: BtGattReadParams) {
        let address = self.context_map.get_address_by_conn_id(conn_id);
        if address.is_none() {
            return;
        }

        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_descriptor_read(
            address.unwrap().to_string(),
            status,
            data.handle as i32,
            data.value.value[0..data.value.len as usize].to_vec(),
        );
    }

    fn write_descriptor_cb(&mut self, conn_id: i32, status: i32, handle: u16) {
        let address = self.context_map.get_address_by_conn_id(conn_id);
        if address.is_none() {
            return;
        }

        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_descriptor_write(
            address.unwrap().to_string(),
            status,
            handle as i32,
        );
    }

    fn execute_write_cb(&mut self, conn_id: i32, status: i32) {
        let address = self.context_map.get_address_by_conn_id(conn_id);
        if address.is_none() {
            return;
        }

        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_execute_write(address.unwrap().to_string(), status);
    }

    fn read_remote_rssi_cb(&mut self, client_id: i32, addr: RawAddress, rssi: i32, status: i32) {
        let client = self.context_map.get_by_client_id(client_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_read_remote_rssi(addr.to_string(), rssi, status);
    }

    fn configure_mtu_cb(&mut self, conn_id: i32, status: i32, mtu: i32) {
        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        let addr = self.context_map.get_address_by_conn_id(conn_id);
        if addr.is_none() {
            return;
        }

        client.unwrap().callback.on_configure_mtu(addr.unwrap(), mtu, status);
    }

    fn congestion_cb(&mut self, conn_id: i32, congested: bool) {
        let client = self.context_map.get_client_by_conn_id_mut(conn_id);
        if client.is_none() {
            return;
        }

        let client = client.unwrap();

        client.is_congested = congested;
        if !client.is_congested {
            for callback in client.congestion_queue.iter() {
                client.callback.on_characteristic_write(callback.0.clone(), callback.1, callback.2);
            }
            client.congestion_queue.clear();
        }
    }

    fn get_gatt_db_cb(&mut self, conn_id: i32, elements: Vec<BtGattDbElement>, _count: i32) {
        let address = self.context_map.get_address_by_conn_id(conn_id);
        if address.is_none() {
            return;
        }

        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        let mut db_out: Vec<BluetoothGattService> = vec![];

        for elem in elements {
            match GattDbElementType::from_u32(elem.type_).unwrap() {
                GattDbElementType::PrimaryService | GattDbElementType::SecondaryService => {
                    db_out.push(BluetoothGattService::new(
                        elem.uuid.uu,
                        elem.id as i32,
                        elem.type_ as i32,
                    ));
                    // TODO(b/200065274): Mark restricted services.
                }

                GattDbElementType::Characteristic => {
                    match db_out.last_mut() {
                        Some(s) => s.characteristics.push(BluetoothGattCharacteristic::new(
                            elem.uuid.uu,
                            elem.id as i32,
                            elem.properties as i32,
                            0,
                        )),
                        None => {
                            // TODO(b/193685325): Log error.
                        }
                    }
                    // TODO(b/200065274): Mark restricted characteristics.
                }

                GattDbElementType::Descriptor => {
                    match db_out.last_mut() {
                        Some(s) => match s.characteristics.last_mut() {
                            Some(c) => c.descriptors.push(BluetoothGattDescriptor::new(
                                elem.uuid.uu,
                                elem.id as i32,
                                0,
                            )),
                            None => {
                                // TODO(b/193685325): Log error.
                            }
                        },
                        None => {
                            // TODO(b/193685325): Log error.
                        }
                    }
                    // TODO(b/200065274): Mark restricted descriptors.
                }

                GattDbElementType::IncludedService => {
                    match db_out.last_mut() {
                        Some(s) => {
                            s.included_services.push(BluetoothGattService::new(
                                elem.uuid.uu,
                                elem.id as i32,
                                elem.type_ as i32,
                            ));
                        }
                        None => {
                            // TODO(b/193685325): Log error.
                        }
                    }
                }
            }
        }

        client.unwrap().callback.on_search_complete(address.unwrap().to_string(), db_out, 0);
    }

    fn phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: u8) {
        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        let address = self.context_map.get_address_by_conn_id(conn_id);
        if address.is_none() {
            return;
        }

        client.unwrap().callback.on_phy_update(
            address.unwrap(),
            LePhy::from_u8(tx_phy).unwrap(),
            LePhy::from_u8(rx_phy).unwrap(),
            GattStatus::from_u8(status).unwrap(),
        );
    }

    fn read_phy_cb(
        &mut self,
        client_id: i32,
        addr: RawAddress,
        tx_phy: u8,
        rx_phy: u8,
        status: u8,
    ) {
        let client = self.context_map.get_by_client_id(client_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_phy_read(
            addr.to_string(),
            LePhy::from_u8(tx_phy).unwrap(),
            LePhy::from_u8(rx_phy).unwrap(),
            GattStatus::from_u8(status).unwrap(),
        );
    }

    fn conn_updated_cb(
        &mut self,
        conn_id: i32,
        interval: u16,
        latency: u16,
        timeout: u16,
        status: u8,
    ) {
        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        let address = self.context_map.get_address_by_conn_id(conn_id);
        if address.is_none() {
            return;
        }

        client.unwrap().callback.on_connection_updated(
            address.unwrap(),
            interval as i32,
            latency as i32,
            timeout as i32,
            status as i32,
        );
    }

    fn service_changed_cb(&self, conn_id: i32) {
        let address = self.context_map.get_address_by_conn_id(conn_id);
        if address.is_none() {
            return;
        }

        let client = self.context_map.get_client_by_conn_id(conn_id);
        if client.is_none() {
            return;
        }

        client.unwrap().callback.on_service_changed(address.unwrap());
    }
}

#[cfg(test)]
mod tests {
    struct TestBluetoothGattCallback {
        id: String,
    }

    impl TestBluetoothGattCallback {
        fn new(id: String) -> TestBluetoothGattCallback {
            TestBluetoothGattCallback { id }
        }
    }

    impl IBluetoothGattCallback for TestBluetoothGattCallback {
        fn on_client_registered(&self, _status: i32, _client_id: i32) {}
        fn on_client_connection_state(
            &self,
            _status: i32,
            _client_id: i32,
            _connected: bool,
            _addr: String,
        ) {
        }

        fn on_phy_update(
            &self,
            _addr: String,
            _tx_phy: LePhy,
            _rx_phy: LePhy,
            _status: GattStatus,
        ) {
        }

        fn on_phy_read(&self, _addr: String, _tx_phy: LePhy, _rx_phy: LePhy, _status: GattStatus) {}

        fn on_search_complete(
            &self,
            _addr: String,
            _services: Vec<BluetoothGattService>,
            _status: i32,
        ) {
        }

        fn on_characteristic_read(
            &self,
            _addr: String,
            _status: i32,
            _handle: i32,
            _value: Vec<u8>,
        ) {
        }

        fn on_characteristic_write(&self, _addr: String, _status: i32, _handle: i32) {}

        fn on_execute_write(&self, _addr: String, _status: i32) {}

        fn on_descriptor_read(&self, _addr: String, _status: i32, _handle: i32, _value: Vec<u8>) {}

        fn on_descriptor_write(&self, _addr: String, _status: i32, _handle: i32) {}

        fn on_notify(&self, _addr: String, _handle: i32, _value: Vec<u8>) {}

        fn on_read_remote_rssi(&self, _addr: String, _rssi: i32, _status: i32) {}

        fn on_configure_mtu(&self, _addr: String, _mtu: i32, _status: i32) {}

        fn on_connection_updated(
            &self,
            _addr: String,
            _interval: i32,
            _latency: i32,
            _timeout: i32,
            _status: i32,
        ) {
        }

        fn on_service_changed(&self, _addr: String) {}
    }

    impl RPCProxy for TestBluetoothGattCallback {
        fn register_disconnect(&mut self, _f: Box<dyn Fn(u32) + Send>) -> u32 {
            0
        }

        fn get_object_id(&self) -> String {
            self.id.clone()
        }

        fn unregister(&mut self, _id: u32) -> bool {
            false
        }
    }

    use super::*;

    #[test]
    fn test_uuid_from_string() {
        let uuid = parse_uuid_string("abcdef");
        assert!(uuid.is_none());

        let uuid = parse_uuid_string("0123456789abcdef0123456789abcdef");
        assert!(uuid.is_some());
        let expected: [u8; 16] = [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
            0xcd, 0xef,
        ];
        assert_eq!(Uuid { uu: expected }, uuid.unwrap());
    }

    #[test]
    fn test_context_map_clients() {
        let mut map = ContextMap::new();

        // Add client 1.
        let callback1 = Box::new(TestBluetoothGattCallback::new(String::from("Callback 1")));
        let uuid1 = parse_uuid_string("00000000000000000000000000000001").unwrap().uu;
        map.add(&uuid1, callback1);
        let found = map.get_by_uuid(&uuid1);
        assert!(found.is_some());
        assert_eq!("Callback 1", found.unwrap().callback.get_object_id());

        // Add client 2.
        let callback2 = Box::new(TestBluetoothGattCallback::new(String::from("Callback 2")));
        let uuid2 = parse_uuid_string("00000000000000000000000000000002").unwrap().uu;
        map.add(&uuid2, callback2);
        let found = map.get_by_uuid(&uuid2);
        assert!(found.is_some());
        assert_eq!("Callback 2", found.unwrap().callback.get_object_id());

        // Set client ID and get by client ID.
        map.set_client_id(&uuid1, 3);
        let found = map.get_by_client_id(3);
        assert!(found.is_some());

        // Remove client 1.
        map.remove(3);
        let found = map.get_by_uuid(&uuid1);
        assert!(found.is_none());
    }

    #[test]
    fn test_context_map_connections() {
        let mut map = ContextMap::new();
        let client_id = 1;

        map.add_connection(client_id, 3, &String::from("aa:bb:cc:dd:ee:ff"));
        map.add_connection(client_id, 4, &String::from("11:22:33:44:55:66"));

        let found = map.get_conn_id_from_address(client_id, &String::from("aa:bb:cc:dd:ee:ff"));
        assert!(found.is_some());
        assert_eq!(3, found.unwrap());

        let found = map.get_conn_id_from_address(client_id, &String::from("11:22:33:44:55:66"));
        assert!(found.is_some());
        assert_eq!(4, found.unwrap());
    }
}
