// Copyright 2023 Google LLC
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// A Uuid as defined by the Core Specification (v5.4, Vol 3, Part B, Sec 2.5.1)
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct Uuid(uuid::Uuid);

impl Uuid {
    // Non-changing parts of the Bluetooth Base UUID, for easy comparison and
    // construction.
    const BASE_UUID_B_PART: u16 = 0x0000;
    const BASE_UUID_C_PART: u16 = 0x1000;
    const BASE_UUID_D_PART: [u8; 8] = [0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB];

    pub const fn from_u16(value: u16) -> Self {
        Self::from_u32(value as u32)
    }

    pub const fn from_u32(value: u32) -> Self {
        Uuid(uuid::Uuid::from_fields(
            value,
            Self::BASE_UUID_B_PART,
            Self::BASE_UUID_C_PART,
            &Self::BASE_UUID_D_PART,
        ))
    }

    pub fn to_u16(&self) -> Option<u16> {
        let x: u32 = self.to_u32()?;
        x.try_into().ok()
    }

    pub fn to_u32(&self) -> Option<u32> {
        let (first, second, third, final_bytes) = self.0.as_fields();
        if second != Uuid::BASE_UUID_B_PART
            || third != Uuid::BASE_UUID_C_PART
            || final_bytes != &Uuid::BASE_UUID_D_PART
        {
            return None;
        }
        Some(first)
    }
}

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

impl From<uuid::Uuid> for Uuid {
    fn from(value: uuid::Uuid) -> Self {
        Uuid(value)
    }
}

impl core::fmt::Display for Uuid {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0.as_hyphenated())
    }
}

impl core::str::FromStr for Uuid {
    type Err = uuid::Error;

    fn from_str(s: &str) -> core::result::Result<Uuid, Self::Err> {
        uuid::Uuid::parse_str(s).map(|uuid| Uuid(uuid))
    }
}

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

    #[test]
    fn uuid16() {
        let uuid = Uuid::from_u16(0x180d);
        assert_eq!("0000180d-0000-1000-8000-00805f9b34fb", uuid.to_string());
        let as16: u16 = uuid.to_u16().unwrap();
        assert_eq!(0x180d, as16);
    }
}
