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

use bitflags::bitflags;

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

pub type Metadata = Vec<Metadatum>;

#[derive(Debug, PartialEq)]
#[repr(u8)]
pub enum Type {
    PreferredAudioContexts = 0x01,
    StreamingAudioContexts = 0x02,
    ProgramInfo = 0x03,
    Language = 0x04,
    CCIDList = 0x05,
    ParentalRating = 0x06,
    ProgramInfoURI = 0x07,
    ExtendedMetadata = 0xfe,
    VendorSpecific = 0xff,
    AudioActiveState = 0x08,
    BroadcastAudioImmediateRenderingFlag = 0x09,
}

impl Type {
    fn length_check(&self, provided: usize) -> Result<(), PacketError> {
        if self.total_size_range().contains(&provided) {
            Ok(())
        } else {
            Err(PacketError::UnexpectedDataLength)
        }
    }

    // Total size range including all Length, Type, and Value parameters.
    fn total_size_range(&self) -> std::ops::Range<usize> {
        match self {
            Type::PreferredAudioContexts | Type::StreamingAudioContexts => 4..5,
            Type::ProgramInfo | Type::CCIDList | Type::ProgramInfoURI => 2..usize::MAX,
            Type::Language => 5..6,
            Type::ParentalRating => 3..4,
            Type::ExtendedMetadata | Type::VendorSpecific => 4..256,
            Type::AudioActiveState => 3..4,
            Type::BroadcastAudioImmediateRenderingFlag => 2..3,
        }
    }
}

impl TryFrom<u8> for Type {
    type Error = PacketError;

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        let t = match value {
            0x01 => Type::PreferredAudioContexts,
            0x02 => Type::StreamingAudioContexts,
            0x03 => Type::ProgramInfo,
            0x04 => Type::Language,
            0x05 => Type::CCIDList,
            0x06 => Type::ParentalRating,
            0x07 => Type::ProgramInfoURI,
            0xFE => Type::ExtendedMetadata,
            0xFF => Type::VendorSpecific,
            0x08 => Type::AudioActiveState,
            0x09 => Type::BroadcastAudioImmediateRenderingFlag,
            _ => return Err(PacketError::OutOfRange),
        };
        Ok(t)
    }
}

#[derive(Debug, PartialEq)]
pub enum Metadatum {
    PreferredAudioContexts(ContextType),
    StreamingAudioContexts(ContextType),
    ProgramInfo(String),
    /// 3 byte, lower case language code as defined in ISO 639-­3
    LanguageCode(String),
    CCIDList(Vec<u8>),
    ParentalRating(Rating),
    ProgramInfoURI(String),
    ExtendedMetadata {
        type_: u16,
        metadata: Vec<u8>,
    },
    VendorSpecific {
        company_id: u16,
        metadata: Vec<u8>,
    },
    AudioActiveState(bool),
    // Flag for Broadcast Audio Immediate Rendering.
    BroadcastAudioImmediateRenderingFlag,
}

impl Metadatum {
    const LENGTH_BYTE_SIZE: usize = 1;
    const TYPE_BYTE_SIZE: usize = 1;
    const MIN_PACKET_SIZE: usize = Self::LENGTH_BYTE_SIZE + Self::TYPE_BYTE_SIZE;

    // Size of this metadatum's Value parameter. Does not include the Length or Type
    // size.
    pub fn value_encoded_len(&self) -> usize {
        match self {
            Metadatum::PreferredAudioContexts(_) => 2,
            Metadatum::StreamingAudioContexts(_) => 2,
            Metadatum::ProgramInfo(value) => value.len(),
            Metadatum::LanguageCode(_) => 3,
            Metadatum::CCIDList(ccids) => ccids.len(),
            Metadatum::ParentalRating(_) => 1,
            Metadatum::ProgramInfoURI(uri) => uri.len(),
            Metadatum::ExtendedMetadata { type_: _, metadata } => 2 + metadata.len(),
            Metadatum::VendorSpecific { company_id: _, metadata } => 2 + metadata.len(),
            Metadatum::AudioActiveState(_) => 1,
            Metadatum::BroadcastAudioImmediateRenderingFlag => 0,
        }
    }

    pub fn type_(&self) -> Type {
        match self {
            Metadatum::PreferredAudioContexts(_) => Type::PreferredAudioContexts,
            Metadatum::StreamingAudioContexts(_) => Type::StreamingAudioContexts,
            Metadatum::ProgramInfo(_) => Type::ProgramInfo,
            Metadatum::LanguageCode(_) => Type::Language,
            Metadatum::CCIDList(_) => Type::CCIDList,
            Metadatum::ParentalRating(_) => Type::ParentalRating,
            Metadatum::ProgramInfoURI(_) => Type::ProgramInfoURI,
            Metadatum::ExtendedMetadata { .. } => Type::ExtendedMetadata,
            Metadatum::VendorSpecific { .. } => Type::VendorSpecific,
            Metadatum::AudioActiveState(_) => Type::AudioActiveState,
            Metadatum::BroadcastAudioImmediateRenderingFlag => {
                Type::BroadcastAudioImmediateRenderingFlag
            }
        }
    }
}

impl Decodable for Metadatum {
    type Error = PacketError;

    fn decode(buf: &[u8]) -> core::result::Result<(Self, usize), Self::Error> {
        if buf.len() < Self::MIN_PACKET_SIZE {
            return Err(PacketError::UnexpectedDataLength);
        }
        // Total length of the buffer including all Length, Type, and Value parameters.
        let total_len = 1 + buf[0] as usize;
        if buf.len() < total_len {
            return Err(PacketError::UnexpectedDataLength);
        }
        let type_ = Type::try_from(buf[1])?;
        let _ = type_.length_check(total_len)?;
        let m: Metadatum = match type_ {
            Type::PreferredAudioContexts | Type::StreamingAudioContexts => {
                let context_type =
                    ContextType::try_from(u16::from_le_bytes(buf[2..4].try_into().unwrap()))?;
                if type_ == Type::PreferredAudioContexts {
                    Self::PreferredAudioContexts(context_type)
                } else {
                    Self::StreamingAudioContexts(context_type)
                }
            }
            Type::ProgramInfo | Type::ProgramInfoURI => {
                let value = String::from_utf8(buf[2..total_len].to_vec())
                    .map_err(|e| PacketError::InvalidParameter(format!("{e}")))?;
                if type_ == Type::ProgramInfo {
                    Self::ProgramInfo(value)
                } else {
                    Self::ProgramInfoURI(value)
                }
            }
            Type::Language => {
                let code = String::from_utf8(buf[2..total_len].to_vec())
                    .map_err(|e| PacketError::InvalidParameter(format!("{e}")))?;
                Self::LanguageCode(code)
            }
            Type::CCIDList => Self::CCIDList(buf[2..total_len].to_vec()),
            Type::ParentalRating => Self::ParentalRating(Rating::decode(&buf[2..3])?.0),
            Type::ExtendedMetadata | Type::VendorSpecific => {
                let type_or_id = u16::from_le_bytes(buf[2..4].try_into().unwrap());
                let data = if buf.len() >= 5 { buf[4..total_len].to_vec() } else { vec![] };
                if type_ == Type::ExtendedMetadata {
                    Self::ExtendedMetadata { type_: type_or_id, metadata: data }
                } else {
                    Self::VendorSpecific { company_id: type_or_id, metadata: data }
                }
            }
            Type::AudioActiveState => {
                if buf[2] > 1 {
                    return Err(PacketError::UnexpectedDataLength);
                }
                Self::AudioActiveState(buf[2] != 0)
            }
            Type::BroadcastAudioImmediateRenderingFlag => {
                Self::BroadcastAudioImmediateRenderingFlag
            }
        };
        return Ok((m, total_len));
    }
}

impl Encodable for Metadatum {
    type Error = PacketError;

    /// Encodes the object into a provided buffer in a Metadata LTV structure.
    /// Bytes are in LSO.
    // See Assigned Numbers section 6.12.6 for details about Metadata LTV
    // structures.
    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
        if buf.len() < self.encoded_len() {
            return Err(PacketError::BufferTooSmall);
        }

        // Length parameter value excludes the length of Length parameter itself (which
        // is 1 byte).
        buf[0] = (self.encoded_len() - 1)
            .try_into()
            .map_err(|_| PacketError::InvalidParameter("Metadata too big".to_string()))?;
        buf[1] = self.type_() as u8;

        match self {
            Self::PreferredAudioContexts(type_) | Self::StreamingAudioContexts(type_) => {
                buf[2..4].copy_from_slice(&type_.bits().to_le_bytes())
            }
            Self::ProgramInfo(value) | Self::ProgramInfoURI(value) => {
                buf[2..2 + value.len()].copy_from_slice(value.as_bytes())
            }
            Self::LanguageCode(value) if value.len() != 3 => {
                return Err(PacketError::InvalidParameter(format!("{self}")));
            }
            Self::LanguageCode(value) => buf[2..5].copy_from_slice(&value.as_bytes()[..3]),
            Self::CCIDList(value) => buf[2..2 + value.len()].copy_from_slice(&value.as_slice()),
            Self::ParentalRating(value) => buf[2] = value.into(),
            Self::ExtendedMetadata { type_, metadata } => {
                buf[2..4].copy_from_slice(&type_.to_le_bytes());
                buf[4..4 + metadata.len()].copy_from_slice(&metadata.as_slice());
            }
            Self::VendorSpecific { company_id, metadata } => {
                buf[2..4].copy_from_slice(&company_id.to_le_bytes());
                buf[4..4 + metadata.len()].copy_from_slice(&metadata.as_slice());
            }
            Self::AudioActiveState(value) => buf[2] = *value as u8,
            Self::BroadcastAudioImmediateRenderingFlag => {}
        }
        Ok(())
    }

    fn encoded_len(&self) -> core::primitive::usize {
        Self::MIN_PACKET_SIZE + self.value_encoded_len()
    }
}

impl std::fmt::Display for Metadatum {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            // TODO(b/308483171): Consider using the Display for the inner fields instead of Debug.
            Metadatum::PreferredAudioContexts(v) => write!(f, "Preferred Audio Contexts: {v:?}"),
            Metadatum::StreamingAudioContexts(v) => write!(f, "Streaming Audio Contexts: {v:?}"),
            Metadatum::ProgramInfo(v) => write!(f, "Progaam Info: {v:?}"),
            Metadatum::LanguageCode(v) => write!(f, "Language: {v:?}"),
            Metadatum::CCIDList(v) => write!(f, "CCID List: {v:?}"),
            Metadatum::ParentalRating(v) => write!(f, "Parental Rating: {v:?}"),
            Metadatum::ProgramInfoURI(v) => write!(f, "Program Info URI: {v:?}"),
            Metadatum::ExtendedMetadata { type_, metadata } => {
                write!(f, "Extended Metadata: type(0x{type_:02x}) metadata({metadata:?})")
            }
            Metadatum::VendorSpecific { company_id, metadata } => {
                write!(f, "Vendor Specific: company(0x{company_id:02x}) metadata({metadata:?})")
            }
            Metadatum::AudioActiveState(v) => write!(f, "Audio Active State: {v}"),
            Metadatum::BroadcastAudioImmediateRenderingFlag => {
                write!(f, "Broadcast Audio Immediate Rendering Flag")
            }
        }
    }
}

bitflags! {
    #[derive(Clone, Copy, Debug, PartialEq)]
    pub struct ContextType: u16 {
        // 0x0000 value is prohibited.
        const UNSPECIFIED      = 0x0001;
        const CONVERSATIONAL   = 0x0002;
        const MEDIA            = 0x0004;
        const GAME             = 0x0008;
        const INSTRUCTIONAL    = 0x0010;
        const VOICE_ASSISTANTS = 0x0020;
        const LIVE             = 0x0040;
        const SOUND_EFFECTS    = 0x0080;
        const NOTIFICATIONS    = 0x0100;
        const RINGTONE         = 0x0200;
        const ALERT            = 0x0400;
        const EMERGENCY_ALARM  = 0x0800;
    }
}

impl TryFrom<u16> for ContextType {
    type Error = PacketError;

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        if u16::count_ones(value) == 0 {
            return Err(PacketError::InvalidParameter(format!("ContextType 0x0000 is prohibited")));
        }
        Ok(ContextType::from_bits_truncate(value))
    }
}

/// Represents recommended minimum age of the viewer.
/// The numbering scheme aligns with Annex F of EN 300 707 v1.2.1
/// published by ETSI.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Rating {
    NoRating,
    AllAge,
    // Recommended for listeners of age x years, where x is the
    // value of u8 that's greater than or equal to 5.
    Age(u8),
}

impl Rating {
    // Minimum age that can be recommended.
    const MIN_RECOMMENDED_AGE: u8 = 5;

    // When recommending for listeners of age Y years,
    // Subtract 3 from the recommended age to get the encoded value.
    // E.g., to indicate recommended age of 8 years or older, encode 5.
    const AGE_OFFSET: u8 = 3;

    const fn no_rating() -> Self {
        Self::NoRating
    }

    const fn all_age() -> Self {
        Self::AllAge
    }

    pub fn min_recommended(age: u8) -> Result<Self, PacketError> {
        if age < Self::MIN_RECOMMENDED_AGE {
            return Err(PacketError::InvalidParameter(format!(
                "minimum recommended age must be at least 5. Got {age}"
            )));
        }
        Ok(Rating::Age(age))
    }
}

impl From<&Rating> for u8 {
    fn from(value: &Rating) -> Self {
        match value {
            Rating::NoRating => 0x00,
            Rating::AllAge => 0x01,
            Rating::Age(a) => a - Rating::AGE_OFFSET,
        }
    }
}

impl Decodable for Rating {
    type Error = PacketError;

    fn decode(buf: &[u8]) -> core::result::Result<(Self, usize), Self::Error> {
        if buf.len() == 0 {
            return Err(PacketError::UnexpectedDataLength);
        }
        let rating = match buf[0] {
            0x00 => Rating::NoRating,
            0x01 => Rating::AllAge,
            value => {
                let age = value.checked_add(Self::AGE_OFFSET).ok_or(PacketError::OutOfRange)?;
                Rating::min_recommended(age).unwrap()
            }
        };
        Ok((rating, 1))
    }
}

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

    #[test]
    fn metadataum_preferred_audio_contexts() {
        // Encoding.
        let test = Metadatum::PreferredAudioContexts(ContextType::CONVERSATIONAL);
        assert_eq!(test.encoded_len(), 4);
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect("should not fail");

        let bytes = vec![0x03, 0x01, 0x02, 0x00];
        assert_eq!(buf, bytes);

        // Decoding.
        let decoded = Metadatum::decode(&buf).expect("should succeed");
        assert_eq!(decoded.0, test);
        assert_eq!(decoded.1, 4);
    }

    #[test]
    fn metadatum_streaming_audio_contexts() {
        // Encoding.
        let test = Metadatum::StreamingAudioContexts(ContextType::RINGTONE | ContextType::ALERT);
        assert_eq!(test.encoded_len(), 4);
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect("should not fail");

        let bytes = vec![0x03, 0x02, 0x00, 0x06];
        assert_eq!(buf, bytes);

        // Decoding.
        let decoded = Metadatum::decode(&buf).expect("should succeed");
        assert_eq!(decoded.0, test);
        assert_eq!(decoded.1, 4);
    }

    #[test]
    fn metadatum_program_info() {
        // Encoding.
        let test = Metadatum::ProgramInfo("a".to_string());
        assert_eq!(test.encoded_len(), 3);
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect("should not fail");

        let bytes = vec![0x02, 0x03, 0x61];
        assert_eq!(buf, bytes);

        // Decoding.
        let decoded = Metadatum::decode(&buf).expect("should succeed");
        assert_eq!(decoded.0, test);
        assert_eq!(decoded.1, 3);
    }

    #[test]
    fn metadatum_language_code() {
        // Encoding.
        let test = Metadatum::LanguageCode("eng".to_string());
        assert_eq!(test.encoded_len(), 5);
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect("should not fail");

        let bytes = vec![0x04, 0x04, 0x65, 0x6E, 0x67];
        assert_eq!(buf, bytes);

        // Decoding.
        let decoded = Metadatum::decode(&buf).expect("should succeed");
        assert_eq!(decoded.0, test);
        assert_eq!(decoded.1, 5);
    }

    #[test]
    fn metadatum_ccid_list() {
        // Encoding.
        let test = Metadatum::CCIDList(vec![0x01, 0x02]);
        assert_eq!(test.encoded_len(), 4);
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect("should not fail");

        let bytes = vec![0x03, 0x05, 0x01, 0x02];
        assert_eq!(buf, bytes);

        // Decoding.
        let decoded = Metadatum::decode(&buf).expect("should succeed");
        assert_eq!(decoded.0, test);
        assert_eq!(decoded.1, 4);
    }

    #[test]
    fn metadatum_parental_rating() {
        // Encding.
        let test = Metadatum::ParentalRating(Rating::Age(8));
        assert_eq!(test.encoded_len(), 0x03);
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect("should not fail");

        let bytes = vec![0x02, 0x06, 0x05];
        assert_eq!(buf, bytes);

        // Decoding.
        let decoded = Metadatum::decode(&buf).expect("should succeed");
        assert_eq!(decoded.0, test);
        assert_eq!(decoded.1, 3);
    }

    #[test]
    fn metadatum_vendor_specific() {
        // Encoding.
        let test = Metadatum::VendorSpecific { company_id: 0x00E0, metadata: vec![0x01, 0x02] };
        assert_eq!(test.encoded_len(), 0x06);
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect("should not fail");

        let bytes = vec![0x05, 0xFF, 0xE0, 0x00, 0x01, 0x02];
        assert_eq!(buf, bytes);

        // Decoding.
        let decoded = Metadatum::decode(&buf).expect("should succeed");
        assert_eq!(decoded.0, test);
        assert_eq!(decoded.1, 6);
    }

    #[test]
    fn metadatum_audio_active_state() {
        // Encoding.
        let test = Metadatum::AudioActiveState(true);
        assert_eq!(test.encoded_len(), 0x03);
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect("should not fail");

        let bytes = vec![0x02, 0x08, 0x01];
        assert_eq!(buf, bytes);

        // Decoding.
        let decoded = Metadatum::decode(&buf).expect("should succeed");
        assert_eq!(decoded.0, test);
        assert_eq!(decoded.1, 3);
    }

    #[test]
    fn metadatum_broadcast_audio_immediate_rendering() {
        // Encoding.
        let test = Metadatum::BroadcastAudioImmediateRenderingFlag;
        assert_eq!(test.encoded_len(), 0x02);
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect("should not fail");

        let bytes = vec![0x01, 0x09];
        assert_eq!(buf, bytes);

        // Decoding.
        let decoded = Metadatum::decode(&buf).expect("should succeed");
        assert_eq!(decoded.0, test);
        assert_eq!(decoded.1, 2);
    }

    #[test]
    fn invalid_metadataum() {
        // Language code must be 3-lettered.
        let test = Metadatum::LanguageCode("illegal".to_string());
        let mut buf = vec![0; test.encoded_len()];
        let _ = test.encode(&mut buf[..]).expect_err("should fail");

        // Not enough length for Length and Type for decoding.
        let buf = vec![0x03];
        let _ = Metadatum::decode(&buf).expect_err("should fail");

        // Not enough length for Value field for decoding.
        let buf = vec![0x02, 0x01, 0x02];
        let _ = Metadatum::decode(&buf).expect_err("should fail");

        // Buffer length does not match Length value for decoding.
        let buf = vec![0x03, 0x03, 0x61];
        let _ = Metadatum::decode(&buf).expect_err("should fail");
    }

    #[test]
    fn rating() {
        let no_rating = Rating::no_rating();
        let all_age = Rating::all_age();
        let for_age = Rating::min_recommended(5).expect("should succeed");

        assert_eq!(<&Rating as Into<u8>>::into(&no_rating), 0x00);
        assert_eq!(<&Rating as Into<u8>>::into(&all_age), 0x01);
        assert_eq!(<&Rating as Into<u8>>::into(&for_age), 0x02);
    }

    #[test]
    fn decode_rating() {
        let res = Rating::decode(&[0]).expect("should not fail");
        assert_eq!(res.0, Rating::NoRating);
        assert_eq!(res.1, 1);

        let res = Rating::decode(&[1]).expect("should not fail");
        assert_eq!(res.0, Rating::AllAge);
        assert_eq!(res.1, 1);

        let res = Rating::decode(&[2]).expect("should not fail");
        assert_eq!(res.0, Rating::Age(5));
        assert_eq!(res.1, 1);

        let res = Rating::decode(&[10]).expect("should not fail");
        assert_eq!(res.0, Rating::Age(13));
        assert_eq!(res.1, 1);
    }

    #[test]
    fn invalid_rating() {
        let _ = Rating::min_recommended(4).expect_err("should have failed");
        let _ = Rating::decode(&[255]).expect_err("should fail");
    }
}
