// Copyright 2018 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 self::constants::{
    CHARACTERISTIC_NUMBERS,
    CUSTOM_SERVICE_UUIDS,
    DESCRIPTOR_NUMBERS,
    SERVICE_UUIDS,
};

mod constants;

/// An assigned number, code, or identifier for a concept in the Bluetooth wireless standard.
/// Includes an associated abbreviation and human-readable name for the number.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AssignedNumber {
    /// Assigned uuid in canonical 8-4-4-4-12 string format
    pub number: &'static str,
    /// Short abbreviation of the `name`
    pub abbreviation: Option<&'static str>,
    /// Human readable name
    pub name: &'static str,
}

impl AssignedNumber {
    /// Tests if an `identifier` matches any of the fields in the assigned number.
    /// Matches are case-insensitive. Matches on the number can be in the canonical
    /// 8-4-4-4-12 uuid string format or the first 8 digits of the uuid with or without
    /// leading 0s.
    pub fn matches(&self, identifier: &str) -> bool {
        let identifier = &identifier.to_uppercase();
        self.matches_abbreviation(identifier) ||
            self.matches_name(identifier) ||
            self.matches_number(identifier)
    }

    fn matches_abbreviation(&self, identifier: &str) -> bool {
        self.abbreviation.map(|abbr| abbr == identifier).unwrap_or(false)
    }

    fn matches_name(&self, identifier: &str) -> bool {
        self.name.to_uppercase() == identifier
    }

    fn short_id(&self) -> &str {
        self.number
            .split("-")
            .next()
            .expect("split iter always has at least 1 item")
    }

    /// Matches full uuid or short form of Bluetooth SIG assigned numbers.
    /// Precondition: identifier should already be uppercase when passed into the method.
    fn matches_number(&self, identifier: &str) -> bool {
        let identifier = if identifier.starts_with("0X") { &identifier[2..] } else { identifier };
        if identifier.len() == 32 + 4 {
            self.number == identifier
        } else {
            // pad out the identifier with leading zeros to a width of 8
            self.short_id() == format!("{:0>8}", identifier)
        }
    }
}

/// Search for the Bluetooth SIG number for a given service identifier
/// and return associated information. `identifier` can be a human readable
/// string, abbreviation, or the number in full uuid format or shortened forms
pub fn find_service_uuid(identifier: &str) -> Option<AssignedNumber> {
    SERVICE_UUIDS
        .iter()
        .chain(CUSTOM_SERVICE_UUIDS.iter())
        .find(|sn| sn.matches(identifier))
        .map(|&an| an)
}

/// Search for the Bluetooth SIG number for a given characteristic identifier
/// and return associated information. `identifier` can be a human readable
/// string or the number in full uuid format or shortened forms
pub fn find_characteristic_number(identifier: &str) -> Option<AssignedNumber> {
    CHARACTERISTIC_NUMBERS.iter().find(|cn| cn.matches(identifier)).map(|&an| an)
}

/// Search for the Bluetooth SIG number for a given descriptor identifier
/// and return associated information. `identifier` can be a human readable
/// string or the number in full uuid format or shortened forms
pub fn find_descriptor_number(identifier: &str) -> Option<AssignedNumber> {
    DESCRIPTOR_NUMBERS.iter().find(|dn| dn.matches(identifier)).map(|&an| an)
}

#[macro_export]
macro_rules! assigned_number {
    ($num:expr, $abbr:expr, $name:expr) => (
        AssignedNumber {
            number: concat!("0000", $num, "-0000-1000-8000-00805F9B34FB"),
            abbreviation: Some($abbr),
            name: $name
        }
    );
    ($num:expr, $name:expr) => (
        AssignedNumber {
            number: concat!("0000", $num, "-0000-1000-8000-00805F9B34FB"),
            abbreviation: None,
            name: $name
        }
    );
}


#[cfg(test)]
mod tests {
    use super::{
        find_characteristic_number,
        find_descriptor_number,
        find_service_uuid,
        CHARACTERISTIC_NUMBERS,
        CUSTOM_SERVICE_UUIDS,
        DESCRIPTOR_NUMBERS,
        SERVICE_UUIDS,
    };

    #[test]
    fn test_find_characteristic_number() {
        assert_eq!(find_characteristic_number("Device Name"), Some(CHARACTERISTIC_NUMBERS[0]));
        assert_eq!(find_characteristic_number("aPPEARANCE"), Some(CHARACTERISTIC_NUMBERS[1]));
        assert_eq!(find_characteristic_number("fake characteristic name"), None);
        assert_eq!(find_characteristic_number("2a00"), Some(CHARACTERISTIC_NUMBERS[0]));
        assert_eq!(find_characteristic_number("zzzz"), None);
    }

    #[test]
    fn test_find_descriptor_number() {
        assert_eq!(find_descriptor_number("Report reference"), Some(DESCRIPTOR_NUMBERS[8]));
        assert_eq!(find_descriptor_number("fake descriptor name"), None);
        assert_eq!(
            find_descriptor_number("00002908-0000-1000-8000-00805F9B34FB"),
            Some(DESCRIPTOR_NUMBERS[8])
        );
        assert_eq!(find_descriptor_number("2908"), Some(DESCRIPTOR_NUMBERS[8]));
        assert_eq!(find_descriptor_number("zzzz"), None);
    }

    #[test]
    fn test_find_service_uuid() {
        assert_eq!(find_service_uuid("GAP"), Some(SERVICE_UUIDS[0]));
        assert_eq!(find_service_uuid("Gap"), Some(SERVICE_UUIDS[0]));
        assert_eq!(find_service_uuid("gap"), Some(SERVICE_UUIDS[0]));
        assert_eq!(find_service_uuid("hIdS"), Some(SERVICE_UUIDS[16]));
        assert_eq!(find_service_uuid("XYZ"), None);
        assert_eq!(find_service_uuid("Human Interface Device Service"), Some(SERVICE_UUIDS[16]));
        assert_eq!(find_service_uuid("Fake Service Name"), None);
        assert_eq!(find_service_uuid("183A"), Some(SERVICE_UUIDS[39]));
        assert_eq!(find_service_uuid("0x183a"), Some(SERVICE_UUIDS[39]));
        assert_eq!(find_service_uuid("0000183a"), Some(SERVICE_UUIDS[39]));
        assert_eq!(find_service_uuid("0000183A-0000-1000-8000-00805F9B34FB"), Some(SERVICE_UUIDS[39]));
        assert_eq!(find_service_uuid("0000183A-0000-1000-8000-000000000000"), None);
        assert_eq!(find_service_uuid("ZZZZZZZZ"), None);
        assert_eq!(find_service_uuid("ZZZZZZZZ-0000-1000-8000-00805F9B34FB"), None);
        // found in CUSTOM_SERVICE_UUIDS
        assert_eq!(find_service_uuid("fdcf"), Some(CUSTOM_SERVICE_UUIDS[0]));
        assert_eq!(find_service_uuid("FDE2"), Some(CUSTOM_SERVICE_UUIDS[19]));
    }
}
