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

pub mod codec_capabilities;

pub mod metadata_ltv;

use crate::{codable_as_bitmask, decodable_enum};

// Source:
// https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/profiles_and_services/generic_audio/context_type.yaml
decodable_enum! {
    pub enum ContextType<u16, crate::packet_encoding::Error, OutOfRange> {
        Unspecified = 0x0001,
        Conversational = 0x0002,
        Media = 0x0004,
        Game = 0x0008,
        Instructional = 0x0010,
        VoiceAssistants = 0x0020,
        Live = 0x0040,
        SoundEffects = 0x0080,
        Notifications = 0x0100,
        Ringtone = 0x0200,
        Alerts = 0x0400,
        EmergencyAlarm = 0x0800,
    }
}

codable_as_bitmask!(ContextType, u16);

// Source:
// https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/profiles_and_services/generic_audio/audio_location_definitions.yaml
// Regexp magic for quick variants:
// %s/ - value: \(\S\+\)\n   audio_location: \(.*\)\n/\2 = \1\r,/g
// with subsequent removal of Spaces
decodable_enum! {
    pub enum AudioLocation<u32, crate::packet_encoding::Error, OutOfRange> {
        FrontLeft = 0x00000001,
        FrontRight = 0x00000002,
        FrontCenter = 0x00000004,
        LowFrequencyEffects1 = 0x00000008,
        BackLeft = 0x00000010,
        BackRight = 0x00000020,
        FrontLeftOfCenter = 0x00000040,
        FrontRightOfCenter = 0x00000080,
        BackCenter = 0x00000100,
        LowFrequencyEffects2 = 0x00000200,
        SideLeft = 0x00000400,
        SideRight = 0x00000800,
        TopFrontLeft = 0x00001000,
        TopFrontRight = 0x00002000,
        TopFrontCenter = 0x00004000,
        TopCenter = 0x00008000,
        TopBackLeft = 0x00010000,
        TopBackRight = 0x00020000,
        TopSideLeft = 0x00040000,
        TopSideRight = 0x00080000,
        TopBackCenter = 0x00100000,
        BottomFrontCenter = 0x00200000,
        BottomFrontLeft = 0x00400000,
        BottomFrontRight = 0x00800000,
        FrontLeftWide = 0x01000000,
        FrontRightWide = 0x02000000,
        LeftSurround = 0x04000000,
        RightSurround = 0x08000000,
    }
}

codable_as_bitmask!(AudioLocation, u32);

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

    #[test]
    fn locations_decodable() {
        let five_point_one = 0b111111;

        let locations: std::collections::HashSet<AudioLocation> =
            AudioLocation::from_bits(five_point_one).collect();

        assert_eq!(6, locations.len());

        let expected_locations = [
            AudioLocation::FrontLeft,
            AudioLocation::FrontRight,
            AudioLocation::FrontCenter,
            AudioLocation::LowFrequencyEffects1,
            AudioLocation::BackLeft,
            AudioLocation::BackRight,
        ]
        .into_iter()
        .collect();

        assert_eq!(locations, expected_locations);

        assert_eq!(AudioLocation::try_from(0x4), Ok(AudioLocation::FrontCenter));

        // Directly decoding a location that is not a single bit is an error.
        assert!(AudioLocation::try_from(0b1010101).is_err());
    }

    #[test]
    fn locations_encodable() {
        let locations_missing_sub = [
            AudioLocation::FrontLeft,
            AudioLocation::FrontRight,
            AudioLocation::FrontCenter,
            AudioLocation::BackLeft,
            AudioLocation::BackRight,
        ];

        let value = AudioLocation::to_bits(locations_missing_sub.iter());

        assert_eq!(0b110111, value);
    }

    #[test]
    fn context_type_decodable() {
        let contexts: Vec<ContextType> = ContextType::from_bits(0b10).collect();
        assert_eq!(contexts.len(), 1);
        assert_eq!(contexts[0], ContextType::Conversational);

        let live_and_instructional = 0b1010000;
        let contexts: std::collections::HashSet<ContextType> =
            ContextType::from_bits(live_and_instructional).collect();

        assert_eq!(contexts.len(), 2);
        assert_eq!(contexts, [ContextType::Live, ContextType::Instructional].into_iter().collect());

        let alerts_and_conversational = 0x0402;

        let contexts: std::collections::HashSet<ContextType> =
            ContextType::from_bits(alerts_and_conversational).collect();

        assert_eq!(contexts.len(), 2);
        assert_eq!(
            contexts,
            [ContextType::Alerts, ContextType::Conversational].into_iter().collect()
        );
    }

    #[test]
    fn context_type_encodable() {
        let contexts = [ContextType::Notifications, ContextType::SoundEffects, ContextType::Game];

        let value = ContextType::to_bits(contexts.iter());

        assert_eq!(0x188, value);
    }
}
