// 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;
}

/// Implement when a type can be deserialized from a characteristic value.
pub trait FromCharacteristic: Sized {
    const UUID: Uuid;

    /// Create this type from a Characteristic and an initial value.
    fn from_chr(
        characteristic: Characteristic,
        value: &[u8],
    ) -> ::core::result::Result<Self, bt_common::packet_encoding::Error>;

    /// Attempt to update the type when supplied with the `new_value`, which may
    /// or may not be the complete value.
    fn update(
        &mut self,
        new_value: &[u8],
    ) -> ::core::result::Result<&mut Self, bt_common::packet_encoding::Error>;
}

#[derive(Debug, Clone)]
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)
    }
}
