// Copyright 2026 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.

//! Contains structs and traits that are used to connect and get information for
//! Connected Isochronous Groups and Streams.

use bt_common::core::CodecId;
use bt_common::decodable_enum;
use bt_common::packet_encoding::{Decodable, Encodable};
use bt_common::PeerId;
use futures::future::{ready, Ready};
use std::future::Future;

decodable_enum! {
pub enum Framing<u8, bt_common::packet_encoding::Error, OutOfRange> {
    Unframed = 0x00,
    Framed = 0x01,
}
}

impl Framing {
    pub const BYTE_SIZE: usize = 1;
}

impl Encodable for Framing {
    type Error = bt_common::packet_encoding::Error;
    fn encoded_len(&self) -> core::primitive::usize {
        Self::BYTE_SIZE
    }
    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
        if buf.len() < Self::BYTE_SIZE {
            return Err(Self::Error::BufferTooSmall);
        }
        buf[0] = (*self).into();
        Ok(())
    }
}

decodable_enum! {
pub enum Packing<u8, bt_common::packet_encoding::Error, OutOfRange> {
    Sequential = 0x00,
    Interleaved = 0x01,
}
}

impl Packing {
    const BYTE_SIZE: usize = 1;
}

impl Encodable for Packing {
    type Error = bt_common::packet_encoding::Error;
    fn encoded_len(&self) -> core::primitive::usize {
        Self::BYTE_SIZE
    }
    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
        if buf.len() < Self::BYTE_SIZE {
            return Err(Self::Error::BufferTooSmall);
        }
        buf[0] = (*self).into();
        Ok(())
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CisId(u8);

impl CisId {
    pub const BYTE_SIZE: usize = 1;
}

impl TryFrom<u8> for CisId {
    type Error = bt_common::packet_encoding::Error;

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        if value > 0xEF {
            Err(Self::Error::OutOfRange)
        } else {
            Ok(CisId(value))
        }
    }
}

impl From<CisId> for u8 {
    fn from(value: CisId) -> Self {
        value.0
    }
}

impl Encodable for CisId {
    type Error = bt_common::packet_encoding::Error;
    fn encoded_len(&self) -> core::primitive::usize {
        Self::BYTE_SIZE
    }
    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
        if buf.len() < Self::BYTE_SIZE {
            return Err(Self::Error::BufferTooSmall);
        }
        buf[0] = self.0;
        Ok(())
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CigId(u8);

impl CigId {
    pub const BYTE_SIZE: usize = 1;
}

impl TryFrom<u8> for CigId {
    type Error = bt_common::packet_encoding::Error;

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        if value > 0xEF {
            Err(Self::Error::OutOfRange)
        } else {
            Ok(CigId(value))
        }
    }
}

impl From<CigId> for u8 {
    fn from(value: CigId) -> Self {
        value.0
    }
}

impl Encodable for CigId {
    type Error = bt_common::packet_encoding::Error;
    fn encoded_len(&self) -> core::primitive::usize {
        Self::BYTE_SIZE
    }
    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
        if buf.len() < Self::BYTE_SIZE {
            return Err(Self::Error::BufferTooSmall);
        }
        buf[0] = self.0;
        Ok(())
    }
}

/// SDU Interval parameter (in milliseconds)
/// This value is 24 bits long and little-endian on the wire.
/// It is stored native-endian here.
/// Valid range is [0x0000FF, 0x0FFFFF].
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct SduInterval(u32);

impl SduInterval {
    pub const BYTE_SIZE: usize = 3;
}

impl TryFrom<std::time::Duration> for SduInterval {
    type Error = bt_common::packet_encoding::Error;
    fn try_from(value: std::time::Duration) -> Result<Self, Self::Error> {
        let Ok(microseconds) = u32::try_from(value.as_micros()) else {
            return Err(Self::Error::OutOfRange);
        };
        if microseconds < 0xFF || microseconds > 0x0FFFFF {
            return Err(Self::Error::OutOfRange);
        }
        Ok(Self(microseconds))
    }
}

impl TryFrom<u32> for SduInterval {
    type Error = bt_common::packet_encoding::Error;
    fn try_from(value: u32) -> Result<Self, Self::Error> {
        if value < 0xFF || value > 0x0FFFFF {
            return Err(Self::Error::OutOfRange);
        }
        Ok(Self(value))
    }
}

impl Decodable for SduInterval {
    type Error = bt_common::packet_encoding::Error;

    fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
        if buf.len() < Self::BYTE_SIZE {
            return (Err(Self::Error::BufferTooSmall), buf.len());
        }
        let val = u32::from_le_bytes([buf[0], buf[1], buf[2], 0]);
        if (val < 0xFF) || (val > 0x0FFFFF) {
            return (Err(Self::Error::OutOfRange), Self::BYTE_SIZE);
        }
        (Ok(SduInterval(val)), Self::BYTE_SIZE)
    }
}

impl Encodable for SduInterval {
    type Error = bt_common::packet_encoding::Error;
    fn encoded_len(&self) -> core::primitive::usize {
        Self::BYTE_SIZE
    }
    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
        if buf.len() < Self::BYTE_SIZE {
            return Err(Self::Error::BufferTooSmall);
        }
        [buf[0], buf[1], buf[2], _] = self.0.to_le_bytes();
        Ok(())
    }
}

/// Max Transport Latency (in milliseconds)
/// Valid range is [0x0005, 0x0FA0].
/// Transmitted in little-endian, Stored in native-endian.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct MaxTransportLatency(u16);

impl Decodable for MaxTransportLatency {
    type Error = bt_common::packet_encoding::Error;

    fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
        if buf.len() < Self::BYTE_SIZE {
            return (Err(Self::Error::BufferTooSmall), buf.len());
        }
        let val = u16::from_le_bytes([buf[0], buf[1]]);
        if val < 0x0005 || val > 0x0FA0 {
            return (Err(Self::Error::OutOfRange), Self::BYTE_SIZE);
        }
        (Ok(MaxTransportLatency(val)), Self::BYTE_SIZE)
    }
}

impl Encodable for MaxTransportLatency {
    type Error = bt_common::packet_encoding::Error;
    fn encoded_len(&self) -> core::primitive::usize {
        Self::BYTE_SIZE
    }
    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
        if buf.len() < 2 {
            return Err(Self::Error::BufferTooSmall);
        }
        [buf[0], buf[1]] = self.0.to_le_bytes();
        Ok(())
    }
}

impl TryFrom<std::time::Duration> for MaxTransportLatency {
    type Error = bt_common::packet_encoding::Error;

    fn try_from(value: std::time::Duration) -> Result<Self, Self::Error> {
        let Ok(milliseconds) = u16::try_from(value.as_millis()) else {
            return Err(Self::Error::OutOfRange);
        };
        Self::try_from(milliseconds)
    }
}

impl TryFrom<u16> for MaxTransportLatency {
    type Error = bt_common::packet_encoding::Error;

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        if !(0x0005..=0x0FA0).contains(&value) {
            return Err(Self::Error::OutOfRange);
        }
        Ok(Self(value))
    }
}

impl MaxTransportLatency {
    pub const BYTE_SIZE: usize = 2;
}

pub struct CigParameters {
    pub sdu_interval_central_to_peripheral: SduInterval,
    pub sdu_interval_peripheral_to_central: SduInterval,
    pub packing: Packing,
    pub framing: Framing,
    pub max_transport_latency_central_to_peripheral: MaxTransportLatency,
    pub max_transport_latency_peripheral_to_central: MaxTransportLatency,
    /// The expected or intended peers to join this CIG, if known. This may be
    /// used to optimize parameters, but may limit the set of peers that can
    /// connect to the group.
    pub expected_peers: Vec<PeerId>,
}

/// Data Direction
/// This is always represented in relation to the controller, so:
/// Input is data that goes from the Host to the Controller (to the peer)
/// Output is data that goes from the Controller to the Host (from the peer)
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum DataDirection {
    Input,
    Output,
}

/// Data Path Id
/// Non-HCI Data Paths are vendor defined
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum DataPathId {
    Hci,
    Vendor(core::num::NonZeroU8),
}

impl DataPathId {
    pub fn hci() -> Self {
        Self::Hci
    }

    pub fn vendor(path_id: core::num::NonZeroU8) -> Self {
        Self::Vendor(path_id)
    }
}

/// Controller Delay
/// Stored in microseconds, only valid up to 4 seconds.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct ControllerDelay {
    microseconds: u32,
}

impl TryFrom<std::time::Duration> for ControllerDelay {
    type Error = bt_common::packet_encoding::Error;

    fn try_from(duration: std::time::Duration) -> Result<Self, Self::Error> {
        if duration > Self::MAX_ALLOWED {
            return Err(bt_common::packet_encoding::Error::OutOfRange);
        }
        Ok(Self { microseconds: duration.as_micros().try_into().unwrap() })
    }
}

impl From<ControllerDelay> for std::time::Duration {
    fn from(delay: ControllerDelay) -> Self {
        Self::from_micros(delay.microseconds.into())
    }
}

impl ControllerDelay {
    // Maximum allowed delay, from Core Spec  Vol 4, Part E 7.8.109
    const MAX_ALLOWED: std::time::Duration = std::time::Duration::from_secs(4);
}

#[derive(Debug, Clone, PartialEq)]
pub struct CisRequestedParameters {
    pub cis_id: CisId,
    pub max_sdu_size_outgoing: u16,
    pub max_sdu_size_incoming: u16,
}

#[derive(Debug)]
pub enum ConnectedIsochronousError {
    NotSupported,
}

pub trait ConnectedIsochronous: Sized {
    type Group: ConnectedIsochronousGroup;
    type InitializeCigFut: Future<
        Output = std::result::Result<Self::Group, ConnectedIsochronousError>,
    >;

    /// Initialize an isochronous group with the specified parameters.
    /// Dropping a ConnectedIsochronous has no side-effects, notably,
    /// initialized groups are not disconnected.
    fn initialize(
        &self,
        group_parameters: CigParameters,
        streams_requested: &[CisRequestedParameters],
    ) -> Self::InitializeCigFut;
}

pub trait ConnectedIsochronousGroup: Sized {
    type ConnectedIsochronousStream: ConnectedIsochronousStream;
    type CreateCisFut: Future<
        Output = std::result::Result<
            Vec<Self::ConnectedIsochronousStream>,
            ConnectedIsochronousError,
        >,
    >;
    type RemoveGroupFut: Future<Output = ()>;

    /// Get the CIG ID that has been assigned to this group. Returns None if the
    /// Group has not been created yet.
    fn cig_id(&self) -> CigId;

    /// Create CISes using existing connections to the listed peers.
    /// Returns a set of streams which are established and ready for data.
    fn create_streams(&self, peers: &[(CisId, PeerId)]) -> Self::CreateCisFut;

    /// Remove this group. All connected streams will be closed and any
    /// remaining calls to `create` will fail.  This future will complete
    /// when the group has been removed and all streams are disconnected.
    fn remove(&self) -> Self::RemoveGroupFut;
}

/// Represents a connected isochronous stream.
/// Streams may be readable and writable using platform-specific methods.
pub trait ConnectedIsochronousStream: Sized {
    type SetupDataPathFut: Future<Output = std::result::Result<(), ConnectedIsochronousError>>;

    /// Get the IDs associated with this stream.
    fn id(&self) -> (CigId, CisId);

    /// Setup a data path for this stream.  This command may be called multiple
    /// times for each DataDirection.  If it is called multiple times with
    /// the same direction, the previous data path will be removed before
    /// the new data path is set up.
    fn setup_data_path(
        &self,
        direction: DataDirection,
        data_path: DataPathId,
        codec: CodecId,
        codec_configuration: &[u8],
        controller_delay: ControllerDelay,
    ) -> Self::SetupDataPathFut;
}

pub struct NotSupported;

impl ConnectedIsochronous for NotSupported {
    type Group = NotSupported;
    type InitializeCigFut = Ready<std::result::Result<Self::Group, ConnectedIsochronousError>>;

    fn initialize(
        &self,
        _group_parameters: CigParameters,
        _streams_requested: &[CisRequestedParameters],
    ) -> Self::InitializeCigFut {
        ready(Err(ConnectedIsochronousError::NotSupported))
    }
}

impl ConnectedIsochronousGroup for NotSupported {
    type ConnectedIsochronousStream = NotSupported;
    type CreateCisFut = Ready<
        std::result::Result<Vec<Self::ConnectedIsochronousStream>, ConnectedIsochronousError>,
    >;
    type RemoveGroupFut = Ready<()>;

    fn create_streams(&self, _peers: &[(CisId, PeerId)]) -> Self::CreateCisFut {
        ready(Err(ConnectedIsochronousError::NotSupported))
    }

    fn remove(&self) -> Self::RemoveGroupFut {
        ready(())
    }

    fn cig_id(&self) -> CigId {
        unreachable!();
    }
}

impl ConnectedIsochronousStream for NotSupported {
    type SetupDataPathFut = Ready<std::result::Result<(), ConnectedIsochronousError>>;

    fn id(&self) -> (CigId, CisId) {
        unreachable!();
    }

    fn setup_data_path(
        &self,
        _direction: DataDirection,
        _data_path: DataPathId,
        _codec: CodecId,
        _codec_configuration: &[u8],
        _controller_delay: ControllerDelay,
    ) -> Self::SetupDataPathFut {
        ready(Err(ConnectedIsochronousError::NotSupported))
    }
}
