// Copyright 2023 Google LLC
// 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");
    }
}
