// Copyright 2023 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::types::*;

use bt_common::{PeerId, Uuid};

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<T: crate::GattTypes> {
    /// 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) -> T::FindServicesFut;
}

pub trait PeerServiceHandle<T: crate::GattTypes> {
    fn uuid(&self) -> Uuid;
    fn is_primary(&self) -> bool;
    fn connect(&self) -> T::ServiceConnectFut;
}

/// 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<T: crate::GattTypes> {
    /// 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>) -> T::CharacteristicDiscoveryFut;

    /// 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],
    ) -> T::ReadFut<'a>;

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

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

    fn write_descriptor<'a>(&self, handle: &Handle, offset: u16, buf: &'a [u8]) -> T::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) -> T::NotificationStream;
}

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

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

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

    pub fn uuid(&self) -> Uuid {
        self.uuid
    }

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

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