// Copyright 2023 Google LLC
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::types::*;

use bt_common::{PeerId, Uuid};
use futures::{Future, Stream};

pub enum ServiceKind {
    Primary,
    Secondary,
}

// A short definition of a service that is either being published or has been discovered on a
// peer.
pub struct PeerServiceDefinition {
    /// Service Handle
    /// When publishing services, unique among all services published with [`Server::publish`].
    pub id: u64,
    /// Whether the service is marked as Primary in the GATT server.
    pub kind: ServiceKind,
    /// The UUID identifying the type of service that this is.
    pub uuid: Uuid,
}

/// GATT Client connected to a particular peer.
/// Holding a struct that implements this should attempt to maintain a LE connection to the peer.
pub trait Client {
    type PeerServiceHandleT: PeerServiceHandle;
    type ServiceResultFut: Future<Output = Result<Vec<Self::PeerServiceHandleT>>> + 'static;

    /// The ID of the peer this is connected to.
    fn peer_id(&self) -> PeerId;

    /// Find services by UUID on the peer.
    /// This may cause as much as a full discovery of all services on the peer if the stack deems it
    /// appropriate.
    /// Service information should be up to date at the time returned.
    fn find_service(&self, uuid: Uuid) -> Self::ServiceResultFut;
}

pub trait PeerServiceHandle {
    type PeerServiceT: PeerService;
    type ConnectFut: Future<Output = Result<Self::PeerServiceT>>;

    fn uuid(&self) -> Uuid;
    fn is_primary(&self) -> bool;
    fn connect(&self) -> Self::ConnectFut;
}

pub struct CharacteristicNotification {
    pub handle: Handle,
    pub value: Vec<u8>,
    pub maybe_truncated: bool,
}

/// A connection to a GATT Service on a Peer.
/// All operations are done synchronously.
pub trait PeerService {
    type CharacteristicsFut: Future<Output = Result<Vec<Characteristic>>>;
    type NotificationStream: Stream<Item = Result<CharacteristicNotification>>;
    type ReadFut<'a>: Future<Output = Result<(usize, bool)>> + 'a;
    type WriteFut<'a>: Future<Output = Result<()>> + 'a;

    /// Discover characteristics on this service.
    /// If `uuid` is provided, only the characteristics matching `uuid` will be returned.
    /// This operation may use either the Discovery All Characteristics of a Service or
    /// Discovery Characteristic by UUID procedures, regardless of `uuid`.
    fn discover_characteristics(&self, uuid: Option<Uuid>) -> Self::CharacteristicsFut;

    /// Read a characteristic into a buffer, given the handle within the service.
    /// On success, returns the size read and whether the value may have been truncated.
    /// By default this will try to use a long read if the `buf` is larger than a normal read will
    /// allow (22 bytes) or if the offset is non-zero.
    fn read_characteristic<'a>(
        &self,
        handle: &Handle,
        offset: u16,
        buf: &'a mut [u8],
    ) -> Self::ReadFut<'a>;

    fn write_characteristic<'a>(
        &self,
        handle: &Handle,
        mode: WriteMode,
        offset: u16,
        buf: &'a [u8],
    ) -> Self::WriteFut<'a>;

    fn read_descriptor<'a>(
        &self,
        handle: &Handle,
        offset: u16,
        buf: &'a mut [u8],
    ) -> Self::ReadFut<'a>;

    fn write_descriptor<'a>(
        &self,
        handle: &Handle,
        offset: u16,
        buf: &'a [u8],
    ) -> Self::WriteFut<'a>;

    /// Subscribe to updates on a Characteristic.
    /// Either notifications or indications will be enabled depending on the properties available,
    /// with indications preferred if they are supported.
    /// Fails if the Characteristic doesn't support indications or notifications.
    /// Errors are delivered through an Err item in the stream.
    /// This will often write to the Client Characteristic Configuration descriptor for the
    /// Characteristic subscribed to.
    /// Updates sent from the peer wlil be delivered to the Stream returned.
    fn subscribe(&self, handle: &Handle) -> Self::NotificationStream;
}

/// Convenience class for communicating with characteristics on a remote peer.
pub struct ServiceCharacteristic<'a, PeerServiceT> {
    service: &'a PeerServiceT,
    characteristic: Characteristic,
    uuid: Uuid,
}

impl<'a, PeerServiceT: PeerService> ServiceCharacteristic<'a, PeerServiceT> {
    pub async fn find(
        service: &'a PeerServiceT,
        uuid: Uuid,
    ) -> Result<Vec<ServiceCharacteristic<'a, PeerServiceT>>> {
        let chrs = service.discover_characteristics(Some(uuid)).await?;
        Ok(chrs
            .into_iter()
            .map(|characteristic| Self {
                service,
                characteristic,
                uuid,
            })
            .collect())
    }
}

impl<'a, PeerServiceT> ServiceCharacteristic<'a, PeerServiceT> {
    pub fn uuid(&self) -> Uuid {
        self.uuid
    }

    pub fn handle(&self) -> &Handle {
        &self.characteristic.handle
    }

    pub fn characteristic(&self) -> &Characteristic {
        &self.characteristic
    }
}

impl<'a, PeerServiceT: PeerService> ServiceCharacteristic<'a, PeerServiceT> {
    pub async fn read(&self, buf: &mut [u8]) -> Result<usize> {
        self.service
            .read_characteristic(self.handle(), 0, buf)
            .await
            .map(|(bytes, _)| bytes)
    }
}
