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

/// Traits and utilities to handle length-type-value structures.
pub mod ltv;

use crate::packet_encoding::{Encodable, Error as PacketError};

/// Represents the Advertising Set ID which is 1 byte long.
/// Follows little endian encoding.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct AdvertisingSetId(pub u8);

impl AdvertisingSetId {
    // Byte size if this is to be encoded.
    pub const BYTE_SIZE: usize = 1;
}

/// Represents the SyncInfo Interval value which is 2 bytes long.
/// Follows little endian encoding.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct PaInterval(pub u16);

impl PaInterval {
    pub const BYTE_SIZE: usize = 2;
    pub const UNKNOWN_VALUE: u16 = 0xFFFF;

    pub const fn unknown() -> Self {
        Self(Self::UNKNOWN_VALUE)
    }
}

impl Encodable for PaInterval {
    type Error = PacketError;

    /// Encodees the PaInterval to 2 byte value using little endian encoding.
    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
        if buf.len() < Self::BYTE_SIZE {
            return Err(PacketError::BufferTooSmall);
        }
        buf[0..Self::BYTE_SIZE].copy_from_slice(&self.0.to_le_bytes());
        Ok(())
    }

    fn encoded_len(&self) -> core::primitive::usize {
        Self::BYTE_SIZE
    }
}

/// Coding Format as defined by the Assigned Numbers Document. Section 2.11.
/// Referenced in the Core Spec 5.3, Volume 4, Part E, Section 7 as well as
/// various other profile specifications.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum CodingFormat {
    MuLawLog,
    ALawLog,
    Cvsd,
    Transparent,
    LinearPcm,
    Msbc,
    Lc3,
    G729a,
    VendorSpecific,
    Unrecognized(u8),
}

impl From<u8> for CodingFormat {
    fn from(value: u8) -> Self {
        match value {
            0x00 => Self::MuLawLog,
            0x01 => Self::ALawLog,
            0x02 => Self::Cvsd,
            0x03 => Self::Transparent,
            0x04 => Self::LinearPcm,
            0x05 => Self::Msbc,
            0x06 => Self::Lc3,
            0x07 => Self::G729a,
            0xFF => Self::VendorSpecific,
            x => Self::Unrecognized(x),
        }
    }
}

impl From<CodingFormat> for u8 {
    fn from(value: CodingFormat) -> Self {
        match value {
            CodingFormat::MuLawLog => 0x00,
            CodingFormat::ALawLog => 0x01,
            CodingFormat::Cvsd => 0x02,
            CodingFormat::Transparent => 0x03,
            CodingFormat::LinearPcm => 0x04,
            CodingFormat::Msbc => 0x05,
            CodingFormat::Lc3 => 0x06,
            CodingFormat::G729a => 0x07,
            CodingFormat::VendorSpecific => 0xFF,
            CodingFormat::Unrecognized(x) => x,
        }
    }
}

impl core::fmt::Display for CodingFormat {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            CodingFormat::MuLawLog => write!(f, "µ-law log"),
            CodingFormat::ALawLog => write!(f, "A-law log"),
            CodingFormat::Cvsd => write!(f, "CVSD"),
            CodingFormat::Transparent => write!(f, "Transparent"),
            CodingFormat::LinearPcm => write!(f, "Linear PCM"),
            CodingFormat::Msbc => write!(f, "mSBC"),
            CodingFormat::Lc3 => write!(f, "LC3"),
            CodingFormat::G729a => write!(f, "G.729A"),
            CodingFormat::VendorSpecific => write!(f, "Vendor Specific"),
            CodingFormat::Unrecognized(x) => write!(f, "Unrecognized ({x})"),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn encode_pa_interval() {
        let mut buf = [0; PaInterval::BYTE_SIZE];
        let interval = PaInterval(0x1004);

        interval.encode(&mut buf[..]).expect("should succeed");
        assert_eq!(buf, [0x04, 0x10]);
    }

    #[test]
    fn encode_pa_interval_fails() {
        let mut buf = [0; 1]; // Not enough buffer space.
        let interval = PaInterval(0x1004);

        interval.encode(&mut buf[..]).expect_err("should fail");
    }
}
