// 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 anyhow::{format_err, Context as _, Error};
use fidl::endpoints;
use fidl_fuchsia_bluetooth_gatt2::{
    Characteristic, CharacteristicNotifierMarker, CharacteristicNotifierRequest,
    CharacteristicNotifierRequestStream, ClientEventStream, ClientProxy, Handle, LongReadOptions,
    ReadOptions, RemoteServiceEventStream, RemoteServiceProxy, ServiceHandle, ServiceInfo,
    ShortReadOptions, WriteMode, WriteOptions,
};
use fidl_fuchsia_bluetooth_le::{
    CentralMarker, CentralProxy, ConnectionEventStream, ConnectionOptions, ConnectionProxy, Filter,
    ScanOptions, ScanResultWatcherMarker, ScanResultWatcherProxy,
};
use fuchsia_async as fasync;
use fuchsia_component as app;
use fuchsia_sync::RwLock;
use futures::{select, StreamExt};
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::Arc;
use tracing::*;

use fuchsia_bluetooth::types::{le::Peer, PeerId, Uuid};

use crate::bluetooth::types::{BleScanResponse, SerializableReadByTypeResult};
use crate::common_utils::common::macros::with_line;

#[derive(Debug)]
struct Client {
    proxy: ClientProxy,
    _connection: ConnectionProxy,
    // Cache of services populated by GattClientFacade.list_services() and
    // watch_services_task.
    services: HashMap<u64, ServiceInfo>,
    // Task that processes Client.WatchServices() results. Started during the
    // initial call to GattClientFacade.list_services().
    watch_services_task: Option<fasync::Task<()>>,
    // Task listening for closed events from `proxy` and `_connection`.
    _events_task: fasync::Task<()>,
}

#[derive(Debug)]
struct Central {
    proxy: CentralProxy,
    _event_task: fasync::Task<Result<(), Error>>,
}

#[derive(Debug)]
struct RemoteService {
    proxy: RemoteServiceProxy,
    _event_task: fasync::Task<()>,
    // Map of characteristic IDs to CharacteristicNotifier tasks.
    notifier_tasks: HashMap<u64, fasync::Task<()>>,
    peer_id: PeerId,
    service_id: u64,
}

#[derive(Debug)]
pub struct InnerGattClientFacade {
    active_remote_service: Option<RemoteService>,
    central: Option<Central>,
    scan_results: HashMap<PeerId, Peer>,
    clients: HashMap<PeerId, Client>,
    scan_task: Option<fasync::Task<()>>,
}

/// Perform Gatt Client operations.
///
/// Note this object is shared among all threads created by server.
///
#[derive(Debug)]
pub struct GattClientFacade {
    inner: Arc<RwLock<InnerGattClientFacade>>,
}

impl GattClientFacade {
    pub fn new() -> GattClientFacade {
        GattClientFacade {
            inner: Arc::new(RwLock::new(InnerGattClientFacade {
                active_remote_service: None,
                central: None,
                scan_results: HashMap::new(),
                clients: HashMap::new(),
                scan_task: None,
            })),
        }
    }

    pub async fn stop_scan(&self) -> Result<(), Error> {
        let tag = "GattClientFacade::stop_scan";
        if self.inner.write().scan_task.take().is_some() {
            info!(tag = &with_line!(tag), "Scan stopped");
        } else {
            info!(tag = &with_line!(tag), "No scan was running");
        }
        Ok(())
    }

    pub async fn start_scan(&self, filter: Option<Filter>) -> Result<(), Error> {
        let tag = "GattClientFacade::start_scan";

        self.inner.write().scan_results.clear();

        // Set the central proxy if necessary and start a central_listener
        GattClientFacade::set_central_proxy(self.inner.clone());

        let central = self
            .inner
            .read()
            .central
            .as_ref()
            .ok_or(format_err!("No central proxy created."))?
            .proxy
            .clone();

        let options = ScanOptions {
            filters: Some(vec![filter.unwrap_or(Filter::default())]),
            ..Default::default()
        };

        let (watcher_proxy, watcher_server) =
            fidl::endpoints::create_proxy::<ScanResultWatcherMarker>()?;

        // Scan doesn't return until scanning has stopped. We don't care when scanning stops, so we
        // can detach a task to run the scan future.
        let scan_fut = central.scan(&options, watcher_server);
        fasync::Task::spawn(async move {
            if let Err(e) = scan_fut.await {
                warn!(tag = &with_line!(tag), "FIDL error during scan: {:?}", e);
            }
        })
        .detach();

        self.inner.write().scan_task = Some(fasync::Task::spawn(
            GattClientFacade::scan_result_watcher_task(self.inner.clone(), watcher_proxy),
        ));

        info!(tag = &with_line!(tag), "Scan started");
        Ok(())
    }

    async fn scan_result_watcher_task(
        inner: Arc<RwLock<InnerGattClientFacade>>,
        watcher_proxy: ScanResultWatcherProxy,
    ) {
        let tag = "GattClientFacade::scan_result_watcher_task";
        let mut event_stream = watcher_proxy.take_event_stream();
        let mut watch_fut = watcher_proxy.watch();
        loop {
            select! {
                  watch_result = watch_fut => {
                     let peers = match watch_result {
                          Ok(peers) => peers,
                          Err(e) => {
                               info!(
                                  tag = &with_line!(tag),
                                   "FIDL error calling ScanResultWatcher::Watch(): {}", e
                               );
                               break;
                           }};
                     for fidl_peer in peers {
                        let peer: Peer = fidl_peer.try_into().unwrap();
                        debug!(tag = &with_line!(tag), "Peer discovered (id: {}, name: {:?})", peer.id, peer.name);
                        inner.write().scan_results.insert(peer.id, peer);
                     }
                     watch_fut = watcher_proxy.watch();
                  },
                  event = event_stream.next() => {
                    if let Some(Err(err)) = event {
                              info!(tag = &with_line!(tag), "ScanResultWatcher error: {:?}", err);
                    }
                    break; // The only events are those that close the protocol.
                  }
            }
        }
        inner.write().scan_task = None;
        info!(tag = &with_line!(tag), "ScanResultWatcher closed");
    }

    async fn active_remote_service_event_task(
        inner: Arc<RwLock<InnerGattClientFacade>>,
        mut event_stream: RemoteServiceEventStream,
    ) {
        let tag = "GattClientFacade::active_remote_service_event_task";
        while let Some(event) = event_stream.next().await {
            match event {
                Ok(_) => {} // There are no events
                Err(e) => {
                    warn!(tag = &with_line!(tag), "RemoteService error: {:?}", e);
                    break;
                }
            }
        }
        info!(tag = &with_line!(tag), "RemoteService closed");
        inner.write().active_remote_service = None;
    }

    pub async fn gattc_connect_to_service(
        &self,
        peer_id: String,
        service_id: u64,
    ) -> Result<(), Error> {
        let tag = "GattClientFacade::gattc_connect_to_service";
        let peer_id = PeerId::from_str(&peer_id)?;

        // Check if the service is already the active service.
        if let Some(service) = self.inner.read().active_remote_service.as_ref() {
            if service.peer_id == peer_id && service.service_id == service_id {
                info!(
                    tag = &with_line!(tag),
                    "Aready connected to service (peer: {}, service: {})", peer_id, service_id
                );
                return Ok(());
            }
        }

        self.inner.write().active_remote_service = None;

        let client_proxy = self.get_client_proxy(peer_id).ok_or_else(|| {
            error!(
                tag = &with_line!(tag),
                "Unable to connect to service {} (not connected to peer {})", service_id, peer_id
            );
            format_err!("Not connected to peer")
        })?;
        let (proxy, server) = endpoints::create_proxy()?;
        client_proxy.connect_to_service(&ServiceHandle { value: service_id }, server)?;
        let event_stream = proxy.take_event_stream();
        let event_task = fasync::Task::spawn(GattClientFacade::active_remote_service_event_task(
            self.inner.clone(),
            event_stream,
        ));
        self.inner.write().active_remote_service = Some(RemoteService {
            proxy,
            _event_task: event_task,
            notifier_tasks: HashMap::new(),
            peer_id,
            service_id,
        });
        Ok(())
    }

    pub async fn gattc_discover_characteristics(&self) -> Result<Vec<Characteristic>, Error> {
        let discover_characteristics_fut = self
            .get_remote_service_proxy()
            .ok_or(format_err!("RemoteService proxy not available"))?
            .discover_characteristics();
        discover_characteristics_fut.await.map_err(|_| format_err!("Failed to send message"))
    }

    async fn gattc_write_char_internal(
        &self,
        id: u64,
        offset: u16,
        write_value: Vec<u8>,
        mode: WriteMode,
    ) -> Result<(), Error> {
        let handle = Handle { value: id };
        let options =
            WriteOptions { offset: Some(offset), write_mode: Some(mode), ..Default::default() };
        let write_fut = self
            .get_remote_service_proxy()
            .ok_or(format_err!("No active service"))?
            .write_characteristic(&handle, &write_value, &options);
        write_fut
            .await
            .map_err(|_| format_err!("Failed to send message"))?
            .map_err(|err| format_err!("Failed to write characteristic: {:?}", err))
    }

    pub async fn gattc_write_char_by_id(&self, id: u64, write_value: Vec<u8>) -> Result<(), Error> {
        self.gattc_write_char_internal(id, 0, write_value, WriteMode::Default).await
    }

    pub async fn gattc_write_long_char_by_id(
        &self,
        id: u64,
        offset: u16,
        write_value: Vec<u8>,
        reliable_mode: bool,
    ) -> Result<(), Error> {
        self.gattc_write_char_internal(
            id,
            offset,
            write_value,
            if reliable_mode { WriteMode::Reliable } else { WriteMode::Default },
        )
        .await
    }

    pub async fn gattc_write_char_by_id_without_response(
        &self,
        id: u64,
        write_value: Vec<u8>,
    ) -> Result<(), Error> {
        self.gattc_write_char_internal(id, 0, write_value, WriteMode::WithoutResponse).await
    }

    async fn gattc_read_char_internal(
        &self,
        id: u64,
        options: ReadOptions,
    ) -> Result<Vec<u8>, Error> {
        let handle = Handle { value: id };
        let read_fut = self
            .get_remote_service_proxy()
            .ok_or(format_err!("RemoteService proxy not available"))?
            .read_characteristic(&handle, &options);
        let read_value = read_fut
            .await
            .map_err(|_| format_err!("Failed to send message"))?
            .map_err(|err| format_err!("Failed to read long characteristic: {:?}", err))?;
        Ok(read_value.value.unwrap())
    }

    pub async fn gattc_read_char_by_id(&self, id: u64) -> Result<Vec<u8>, Error> {
        self.gattc_read_char_internal(id, ReadOptions::ShortRead(ShortReadOptions {})).await
    }

    pub async fn gattc_read_long_char_by_id(
        &self,
        id: u64,
        offset: u16,
        max_bytes: u16,
    ) -> Result<Vec<u8>, Error> {
        self.gattc_read_char_internal(
            id,
            ReadOptions::LongRead(LongReadOptions {
                offset: Some(offset),
                max_bytes: Some(max_bytes),
                ..Default::default()
            }),
        )
        .await
    }

    pub async fn gattc_read_char_by_type(
        &self,
        raw_uuid: String,
    ) -> Result<Vec<SerializableReadByTypeResult>, Error> {
        let uuid = Uuid::from_str(&raw_uuid)
            .map_err(|e| format_err!("Unable to convert to Uuid: {:?}", e))?;
        let fidl_uuid = fidl_fuchsia_bluetooth::Uuid::from(uuid);
        let read_fut = self
            .get_remote_service_proxy()
            .ok_or(format_err!("RemoteService proxy not available"))?
            .read_by_type(&fidl_uuid);
        let results = read_fut
            .await
            .map_err(|err| format_err!("FIDL error: {:?}", err))?
            .map_err(|err| format_err!("Failed to read characteristic by type: {:?}", err))?
            .into_iter()
            .filter(|r| r.error.is_none())
            .map(|r| SerializableReadByTypeResult::new(r).unwrap())
            .collect();
        Ok(results)
    }

    async fn gattc_read_desc_internal(
        &self,
        id: u64,
        options: ReadOptions,
    ) -> Result<Vec<u8>, Error> {
        let handle = Handle { value: id };
        let read_fut = self
            .get_remote_service_proxy()
            .ok_or(format_err!("RemoteService proxy not available"))?
            .read_descriptor(&handle, &options);
        let read_value = read_fut
            .await
            .map_err(|_| format_err!("Failed to send message"))?
            .map_err(|err| format_err!("Failed to read descriptor: {:?}", err))?;
        Ok(read_value.value.unwrap())
    }

    pub async fn gattc_read_desc_by_id(&self, id: u64) -> Result<Vec<u8>, Error> {
        self.gattc_read_desc_internal(id, ReadOptions::ShortRead(ShortReadOptions {})).await
    }

    pub async fn gattc_read_long_desc_by_id(
        &self,
        id: u64,
        offset: u16,
        max_bytes: u16,
    ) -> Result<Vec<u8>, Error> {
        self.gattc_read_desc_internal(
            id,
            ReadOptions::LongRead(LongReadOptions {
                offset: Some(offset),
                max_bytes: Some(max_bytes),
                ..Default::default()
            }),
        )
        .await
    }

    pub async fn gattc_write_desc_by_id(&self, id: u64, write_value: Vec<u8>) -> Result<(), Error> {
        self.gattc_write_long_desc_by_id(id, 0, write_value).await
    }

    pub async fn gattc_write_long_desc_by_id(
        &self,
        id: u64,
        offset: u16,
        write_value: Vec<u8>,
    ) -> Result<(), Error> {
        let handle = Handle { value: id };
        let options = WriteOptions { offset: Some(offset), ..Default::default() };
        let write_fut = self
            .get_remote_service_proxy()
            .ok_or(format_err!("RemoteService proxy not available"))?
            .write_descriptor(&handle, &write_value, &options);
        write_fut
            .await
            .map_err(|_| format_err!("Failed to send message"))?
            .map_err(|err| format_err!("Failed to write descriptor: {:?}", err))
    }

    async fn notifier_task(
        inner: Arc<RwLock<InnerGattClientFacade>>,
        id: u64,
        mut request_stream: CharacteristicNotifierRequestStream,
    ) {
        let tag = "GattClientFacade::notifier_task";
        while let Ok(event) = request_stream.select_next_some().await {
            match event {
                CharacteristicNotifierRequest::OnNotification { value, responder } => {
                    info!(
                        tag = &with_line!(tag),
                        "Received notification (id: {}, value: {:?})",
                        id,
                        value.value.unwrap()
                    );
                    let _ = responder.send();
                }
            }
        }
        info!(tag = &with_line!(tag), "CharacteristicNotifier closed (id: {})", id);
        inner.write().active_remote_service.as_mut().and_then(|s| s.notifier_tasks.remove(&id));
    }

    pub async fn gattc_toggle_notify_characteristic(
        &self,
        id: u64,
        enable: bool,
    ) -> Result<(), Error> {
        let (register_fut, request_stream) = {
            let mut inner = self.inner.write();
            let service = inner
                .active_remote_service
                .as_mut()
                .ok_or(format_err!("Not connected to a service"))?;

            if !enable {
                service.notifier_tasks.remove(&id);
                return Ok(());
            }
            if service.notifier_tasks.contains_key(&id) {
                return Ok(());
            }

            let (client_end, request_stream) =
                fidl::endpoints::create_request_stream::<CharacteristicNotifierMarker>()?;
            let register_fut =
                service.proxy.register_characteristic_notifier(&Handle { value: id }, client_end);

            (register_fut, request_stream)
        };
        register_fut
            .await
            .map_err(|e| format_err!("FIDL error: {:?}", e))?
            .map_err(|e| format_err!("Error registering notifier: {:?}", e))?;

        let notifier_task = fasync::Task::spawn(GattClientFacade::notifier_task(
            self.inner.clone(),
            id,
            request_stream,
        ));
        self.inner
            .write()
            .active_remote_service
            .as_mut()
            .ok_or(format_err!("Not connected to a service"))?
            .notifier_tasks
            .insert(id, notifier_task);
        Ok(())
    }

    // Warning: hangs forever if there are no service updates!
    async fn watch_services_and_update_map(
        inner: &Arc<RwLock<InnerGattClientFacade>>,
        peer_id: &PeerId,
    ) -> Result<(), Error> {
        let client_proxy = inner
            .read()
            .clients
            .get(peer_id)
            .ok_or(format_err!("Not connected to peer"))?
            .proxy
            .clone();
        let watch_fut = client_proxy.watch_services(&[]);
        let (updated, removed) =
            watch_fut.await.map_err(|_| format_err!("FIDL error calling WatchServices()"))?;

        // watch_services() returns a diff from the previous call, so we need to apply the diff to
        // the cached services to get an updated list of services.
        let mut inner = inner.write();
        let services = &mut inner
            .clients
            .get_mut(peer_id)
            .ok_or(format_err!("Not connected to peer"))?
            .services;
        for handle in removed {
            services.remove(&handle.value);
        }
        for svc in updated {
            services.insert(svc.handle.unwrap().value, svc);
        }
        Ok(())
    }

    async fn watch_services_task(inner: Arc<RwLock<InnerGattClientFacade>>, peer_id: PeerId) -> () {
        loop {
            let tag = "GattClientFacade::watch_services_task";
            if let Err(err) =
                GattClientFacade::watch_services_and_update_map(&inner, &peer_id).await
            {
                warn!(tag = &with_line!(tag), "{}", err);
                return;
            }
        }
    }

    pub async fn list_services(&self, id: String) -> Result<Vec<ServiceInfo>, Error> {
        let peer_id = PeerId::from_str(&id).map_err(|_| format_err!("Invalid peer id"))?;

        {
            let inner = self.inner.read();
            let client = inner.clients.get(&peer_id).ok_or(format_err!("Not connected to peer"))?;
            // If watch_services_task has already been started, then client.services has the latest cached list of services and we can simply return then.
            if client.watch_services_task.is_some() {
                return Ok(client.services.iter().map(|(_, svc)| svc.clone()).collect());
            }
        }

        // On the first call to list_services(), we need to get the initial list of services and start a task to get updates.
        GattClientFacade::watch_services_and_update_map(&self.inner, &peer_id).await?;
        let task =
            fasync::Task::spawn(GattClientFacade::watch_services_task(self.inner.clone(), peer_id));
        let mut inner = self.inner.write();
        let client = inner.clients.get_mut(&peer_id).ok_or(format_err!("Not connected to peer"))?;
        client.watch_services_task = Some(task);

        Ok(client.services.iter().map(|(_, svc)| svc.clone()).collect())
    }

    pub fn get_client_proxy(&self, id: PeerId) -> Option<ClientProxy> {
        self.inner.read().clients.get(&id).map(|c| c.proxy.clone())
    }

    async fn central_event_task(inner: Arc<RwLock<InnerGattClientFacade>>) -> Result<(), Error> {
        let tag = "GattClientFacade::central_event_task";

        let stream = inner
            .write()
            .central
            .as_ref()
            .ok_or(format_err!("Central not set"))?
            .proxy
            .take_event_stream();

        stream.map(|_| ()).collect::<()>().await;

        info!(tag = &with_line!(tag), "Central closed");
        inner.write().central.take();
        return Ok(());
    }

    // If no proxy exists, set up central server to listen for events.
    // Otherwise, do nothing.
    pub fn set_central_proxy(inner: Arc<RwLock<InnerGattClientFacade>>) {
        if inner.read().central.is_some() {
            return;
        }
        let proxy = app::client::connect_to_protocol::<CentralMarker>()
            .context("Failed to connect to BLE Central service.")
            .unwrap();
        let event_task = fasync::Task::spawn(GattClientFacade::central_event_task(inner.clone()));
        inner.write().central = Some(Central { proxy, _event_task: event_task });
    }

    async fn connection_event_task(
        inner: Arc<RwLock<InnerGattClientFacade>>,
        mut connection_stream: ConnectionEventStream,
        mut client_stream: ClientEventStream,
        peer_id: PeerId,
    ) {
        let tag = "GattClientFacade::connection_event_task";
        select! {
           _ = connection_stream.next() => info!(tag = &with_line!(tag) , "Connection to {} closed", peer_id),
           _ = client_stream.next() => info!(tag = &with_line!(tag), "Client for {} closed", peer_id),
        }
        inner.write().clients.remove(&peer_id);
    }

    pub async fn connect_peripheral(&self, id: String) -> Result<(), Error> {
        let tag = "GattClientFacade::connect_peripheral";
        let peer_id = PeerId::from_str(&id)?;

        if self.inner.read().clients.contains_key(&peer_id) {
            info!(tag = &with_line!(tag), "Already connected to {}", peer_id);
            return Ok(());
        }

        GattClientFacade::set_central_proxy(self.inner.clone());

        let (conn_proxy, conn_server_end) = fidl::endpoints::create_proxy()?;
        let options = ConnectionOptions { bondable_mode: Some(true), ..Default::default() };
        self.inner
            .read()
            .central
            .as_ref()
            .unwrap()
            .proxy
            .connect(&peer_id.clone().into(), &options, conn_server_end)
            .map_err(|_| format_err!("FIDL error when trying to connect()"))?;

        let (client_proxy, client_server_end) = fidl::endpoints::create_proxy()?;
        conn_proxy.request_gatt_client(client_server_end)?;

        let events_task = fasync::Task::spawn(GattClientFacade::connection_event_task(
            self.inner.clone(),
            conn_proxy.take_event_stream(),
            client_proxy.take_event_stream(),
            peer_id.clone(),
        ));

        self.inner.write().clients.insert(
            peer_id,
            Client {
                proxy: client_proxy,
                _connection: conn_proxy,
                services: HashMap::new(),
                watch_services_task: None,
                _events_task: events_task,
            },
        );

        Ok(())
    }

    pub async fn disconnect_peripheral(&self, id: String) -> Result<(), Error> {
        let peer_id = PeerId::from_str(&id)?;
        self.inner.write().clients.remove(&peer_id);
        Ok(())
    }

    // Return the central proxy
    pub fn get_central_proxy(&self) -> Option<CentralProxy> {
        self.inner.read().central.as_ref().map(|c| c.proxy.clone())
    }

    fn get_remote_service_proxy(&self) -> Option<RemoteServiceProxy> {
        self.inner.read().active_remote_service.as_ref().map(|s| s.proxy.clone())
    }

    // Returns scan responses converted to BleScanResponses
    pub fn get_scan_responses(&self) -> Vec<BleScanResponse> {
        const EMPTY_DEVICE: &str = "";
        let mut devices = Vec::new();
        for (peer_id, peer) in &self.inner.read().scan_results {
            let id = format!("{}", peer_id);
            let name = peer.name.clone().unwrap_or(EMPTY_DEVICE.to_string());
            let connectable = peer.connectable;
            devices.push(BleScanResponse::new(id, name, connectable));
        }
        devices
    }

    pub fn print(&self) {
        let tag = "GattClientFacade::print";
        let inner = self.inner.read();
        info!(
            tag = &with_line!(tag),
            "Central: {:?}, Active Service: {:?}, Scan Results: {:?}, Clients: {:?}",
            inner.central,
            inner.active_remote_service,
            inner.scan_results,
            inner.clients,
        );
    }

    pub fn cleanup(&self) {
        let mut inner = self.inner.write();
        inner.active_remote_service = None;
        inner.central = None;
        inner.scan_results.clear();
        inner.clients.clear();
        inner.scan_task = None;
    }
}
