// Copyright 2026 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 bt_common::Uuid;
use bt_gatt::types::{
    AttributePermissions, CharacteristicProperties, CharacteristicProperty, GattError, Handle,
    SecurityLevels,
};
use bt_gatt::Characteristic;

use crate::types::*;
use crate::Error;

// ============================================================================
// Characteristic Definitions & Handles (MCS v1.0.1 Section 3)
// ============================================================================

/// Handle assigned to the Media Player Name characteristic.
pub(crate) const MEDIA_PLAYER_NAME_HANDLE: Handle = Handle(1);
/// Handle assigned to the Track Changed characteristic.
pub(crate) const TRACK_CHANGED_HANDLE: Handle = Handle(2);
/// Handle assigned to the Track Title characteristic.
pub(crate) const TRACK_TITLE_HANDLE: Handle = Handle(3);
/// Handle assigned to the Track Duration characteristic.
pub(crate) const TRACK_DURATION_HANDLE: Handle = Handle(4);
/// Handle assigned to the Track Position characteristic.
pub(crate) const TRACK_POSITION_HANDLE: Handle = Handle(5);
/// Handle assigned to the Media State characteristic.
pub(crate) const MEDIA_STATE_HANDLE: Handle = Handle(6);
/// Handle assigned to the Content Control ID (CCID) characteristic.
pub(crate) const CONTENT_CONTROL_ID_HANDLE: Handle = Handle(7);

// ============================================================================
// Optional Characteristic Handle Definitions (MCS v1.0.1 Section 3)
// ============================================================================

/// Handle assigned to the Media Player Icon URL characteristic.
pub(crate) const MEDIA_PLAYER_ICON_URL_HANDLE: Handle = Handle(8);
/// Handle assigned to the Playback Speed characteristic.
pub(crate) const PLAYBACK_SPEED_HANDLE: Handle = Handle(9);
/// Handle assigned to the Seeking Speed characteristic.
pub(crate) const SEEKING_SPEED_HANDLE: Handle = Handle(10);
/// Handle assigned to the Playing Order characteristic.
pub(crate) const PLAYING_ORDER_HANDLE: Handle = Handle(11);
/// Handle assigned to the Playing Orders Supported characteristic.
pub(crate) const PLAYING_ORDERS_SUPPORTED_HANDLE: Handle = Handle(12);
/// Handle assigned to the Media Control Point characteristic.
pub(crate) const MEDIA_CONTROL_POINT_HANDLE: Handle = Handle(13);
/// Handle assigned to the Media Control Point Opcodes Supported characteristic.
pub(crate) const MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE: Handle = Handle(14);

/// Constructs a characteristic definition with the specified handle, UUID,
/// properties, and encryption-required permissions conforming to MCS v1.0.1
/// Section 3.
pub(crate) fn build_characteristic(
    handle: Handle,
    uuid: Uuid,
    properties: impl Into<CharacteristicProperties>,
) -> Characteristic {
    let properties = properties.into();
    Characteristic {
        handle,
        uuid,
        properties,
        permissions: AttributePermissions::with_levels(
            &properties,
            &SecurityLevels::encryption_required(),
        ),
        descriptors: Vec::new(),
    }
}

/// The mandatory characteristics defined in MCS v1.0.1 Section 3, Table 3.1.
pub(crate) fn mandatory_characteristics() -> [Characteristic; 7] {
    [
        build_characteristic(
            MEDIA_PLAYER_NAME_HANDLE,
            MEDIA_PLAYER_NAME_UUID,
            CharacteristicProperties::READ_NOTIFY,
        ),
        build_characteristic(
            TRACK_CHANGED_HANDLE,
            TRACK_CHANGED_UUID,
            CharacteristicProperty::Notify,
        ),
        build_characteristic(
            TRACK_TITLE_HANDLE,
            TRACK_TITLE_UUID,
            CharacteristicProperties::READ_NOTIFY,
        ),
        build_characteristic(
            TRACK_DURATION_HANDLE,
            TRACK_DURATION_UUID,
            CharacteristicProperties::READ_NOTIFY,
        ),
        build_characteristic(
            TRACK_POSITION_HANDLE,
            TRACK_POSITION_UUID,
            CharacteristicProperties::READ_WRITE_NOTIFY,
        ),
        build_characteristic(
            MEDIA_STATE_HANDLE,
            MEDIA_STATE_UUID,
            CharacteristicProperties::READ_NOTIFY,
        ),
        build_characteristic(
            CONTENT_CONTROL_ID_HANDLE,
            CONTENT_CONTROL_ID_UUID,
            CharacteristicProperty::Read,
        ),
    ]
}

/// Local state of the characteristics in this server.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct McsLocalState {
    /// Content Control ID (CCID) identifying this media service instance.
    pub(crate) ccid: u8,
    /// Human-readable media player application name.
    pub(crate) player_name: String,
    /// Title of the currently selected track (empty if no track loaded).
    pub(crate) track_title: String,
    /// Total duration of the current track (MCS v1.0.1 Section 3.6).
    pub(crate) track_duration: TrackDuration,
    /// Base playback position of the current track (MCS v1.0.1 Section 3.7).
    pub(crate) track_position: TrackPosition,
    /// Timestamp when `track_position` was set or updated.
    pub(crate) position_updated_at: Option<std::time::Instant>,
    /// Current player activity state.
    pub(crate) media_state: MediaState,
    /// URL pointing to media player icon graphic, if supported.
    pub(crate) icon_url: Option<String>,
    /// Playback speed multiplier, if supported.
    pub(crate) playback_speed: Option<PlaybackSpeed>,
    /// Seeking speed factor, if supported.
    pub(crate) seeking_speed: Option<SeekingSpeed>,
    /// Playing order and supported playing orders, if supported.
    pub(crate) playing_orders: Option<PlayingOrderState>,
    /// Supported media control point opcodes, if Media Control Point is
    /// supported.
    pub(crate) supported_opcodes: Option<SupportedOpcodes>,
}

impl McsLocalState {
    /// Creates a new [`McsLocalState`] with default values for an inactive
    /// player with no track loaded per MCS v1.0.1 Section 3.
    pub(crate) fn new(ccid: u8, player_name: impl Into<String>) -> Self {
        Self {
            ccid,
            player_name: player_name.into(),
            track_title: String::new(),
            track_duration: TrackDuration::Unknown,
            track_position: TrackPosition::Unavailable,
            position_updated_at: None,
            media_state: MediaState::Inactive,
            icon_url: None,
            playback_speed: None,
            seeking_speed: None,
            playing_orders: None,
            supported_opcodes: None,
        }
    }

    /// Calculates the instantaneous track position based on elapsed playback
    /// time (MCS v1.0.1 Section 3.7).
    pub(crate) fn current_track_position(&self) -> TrackPosition {
        // Per MCS Section 3.17, an inactive player has no current track, so it
        // is unavailable.
        if self.media_state == MediaState::Inactive {
            return TrackPosition::Unavailable;
        }

        let base = match (self.track_position, self.track_duration) {
            (TrackPosition::FromStart(base), _) => base,
            (TrackPosition::FromEnd(end), TrackDuration::Duration(total)) => {
                total.saturating_sub(end)
            }
            (TrackPosition::FromEnd(_), TrackDuration::Unknown) => {
                return TrackPosition::Unavailable;
            }
            _ => return self.track_position,
        };

        // Playback is paused, so position remains fixed at current offset.
        if self.media_state == MediaState::Paused {
            return TrackPosition::FromStart(base);
        }

        // Playback timing has not started since the track was initialized or
        // loaded.
        let Some(updated_at) = self.position_updated_at else {
            return TrackPosition::FromStart(base);
        };

        let elapsed = updated_at.elapsed();
        let current = match self.media_state {
            MediaState::Playing => {
                let speed_multiplier = self.playback_speed.map_or(1.0, |s| s.as_multiplier());
                base + elapsed.mul_f64(speed_multiplier)
            }
            MediaState::Seeking => {
                let factor = self.seeking_speed.map_or(0, |s| s.factor());
                if factor > 0 {
                    base + elapsed.mul_f64(factor as f64)
                } else if factor < 0 {
                    base.saturating_sub(elapsed.mul_f64(factor.unsigned_abs() as f64))
                } else {
                    base
                }
            }
            _ => base,
        };

        let bounded = if let TrackDuration::Duration(total) = self.track_duration {
            current.min(total)
        } else {
            current
        };

        TrackPosition::FromStart(bounded)
    }

    /// Updates the track position and synchronizes the timestamp anchor.
    fn update_track_position(&mut self, position: TrackPosition) {
        let resolved = match (position, self.track_duration) {
            (TrackPosition::FromStart(base), _) => TrackPosition::FromStart(base),
            (TrackPosition::FromEnd(end), TrackDuration::Duration(total)) => {
                TrackPosition::FromStart(total.saturating_sub(end))
            }
            (TrackPosition::FromEnd(_), TrackDuration::Unknown) => TrackPosition::Unavailable,
            (TrackPosition::Unavailable, _) => TrackPosition::Unavailable,
        };
        self.track_position = resolved;
        self.position_updated_at = match resolved {
            TrackPosition::Unavailable => None,
            _ => Some(std::time::Instant::now()),
        };
    }

    /// Sets the media playback state and updates the playback position clock
    /// anchor accordingly.
    pub(crate) fn set_media_state(&mut self, state: MediaState) {
        if self.media_state == state {
            return;
        }

        match state {
            MediaState::Playing | MediaState::Paused | MediaState::Seeking => {
                let position = if self.media_state == MediaState::Playing
                    || self.media_state == MediaState::Seeking
                {
                    self.current_track_position()
                } else {
                    self.track_position
                };
                self.update_track_position(position);
            }
            MediaState::Inactive => {
                self.update_track_position(TrackPosition::Unavailable);
            }
        }
        self.media_state = state;
    }

    /// Sets the track position and records the update timestamp.
    pub(crate) fn set_track_position(&mut self, position: TrackPosition) {
        self.update_track_position(position);
    }

    /// Sets the current track title, duration, and position.
    pub(crate) fn set_track(
        &mut self,
        title: String,
        duration: TrackDuration,
        position: TrackPosition,
    ) {
        self.track_title = title;
        self.track_duration = duration;
        self.update_track_position(position);
    }

    /// Clears the active track metadata and position.
    pub(crate) fn clear_track(&mut self) {
        self.track_title.clear();
        self.track_duration = TrackDuration::Unknown;
        self.update_track_position(TrackPosition::Unavailable);
    }

    /// Sets the human-readable media player name.
    pub(crate) fn set_player_name(&mut self, name: String) {
        self.player_name = name;
    }

    /// Sets the media player icon URL if supported.
    pub(crate) fn set_icon_url(&mut self, url: String) -> Result<(), Error> {
        if self.icon_url.is_none() {
            return Err(Error::FeatureNotSupported("icon_url"));
        }
        self.icon_url = Some(url);
        Ok(())
    }

    /// Sets the playback speed.
    pub(crate) fn set_playback_speed(&mut self, speed: PlaybackSpeed) -> Result<(), Error> {
        if self.playback_speed.is_none() {
            return Err(Error::FeatureNotSupported("playback_speed"));
        }
        // Freeze current track position before adjusting speed so the new
        // multiplier is not retroactively applied to prior playback
        // time (MCS v1.0.1 Section 3.7.1).
        if self.media_state == MediaState::Playing {
            self.update_track_position(self.current_track_position());
        }
        self.playback_speed = Some(speed);
        Ok(())
    }

    /// Sets the seeking speed if supported.
    pub(crate) fn set_seeking_speed(&mut self, speed: SeekingSpeed) -> Result<(), Error> {
        if self.seeking_speed.is_none() {
            return Err(Error::FeatureNotSupported("seeking_speed"));
        }
        // Freeze current track position before entering or adjusting seeking
        // speed so prior elapsed playback is preserved (MCS v1.0.1
        // Section 3.7.1, 3.9).
        if self.media_state == MediaState::Playing || self.media_state == MediaState::Seeking {
            self.update_track_position(self.current_track_position());
        }
        self.seeking_speed = Some(speed);
        Ok(())
    }

    /// Sets the playing order if supported and enabled.
    pub(crate) fn set_playing_order(&mut self, order: PlayingOrder) -> Result<(), Error> {
        let Some(ref mut orders) = self.playing_orders else {
            return Err(Error::FeatureNotSupported("playing_orders"));
        };
        if !orders.supported.contains(order.into()) {
            return Err(Error::UnsupportedPlayingOrder(order));
        }
        orders.current = order;
        Ok(())
    }

    /// Sets the supported opcodes if supported.
    pub(crate) fn set_supported_opcodes(&mut self, opcodes: SupportedOpcodes) -> Result<(), Error> {
        if self.supported_opcodes.is_none() {
            return Err(Error::FeatureNotSupported("media_control_point"));
        }
        self.supported_opcodes = Some(opcodes);
        Ok(())
    }

    /// Reads the characteristic bytes for `handle` at `offset`.
    pub(crate) fn handle_read(&self, handle: Handle, offset: usize) -> Result<Vec<u8>, GattError> {
        let read_at_offset =
            |bytes: &[u8]| bytes.get(offset..).map(Vec::from).ok_or(GattError::InvalidOffset);

        match handle {
            // Track Changed and Media Control Point are not readable per MCS v1.0.1 Section 3,
            // Table 3.1.
            TRACK_CHANGED_HANDLE | MEDIA_CONTROL_POINT_HANDLE => Err(GattError::ReadNotPermitted),
            MEDIA_PLAYER_NAME_HANDLE => read_at_offset(self.player_name.as_bytes()),
            TRACK_TITLE_HANDLE => read_at_offset(self.track_title.as_bytes()),
            TRACK_DURATION_HANDLE => read_at_offset(&self.track_duration.raw_10ms().to_le_bytes()),
            TRACK_POSITION_HANDLE => {
                read_at_offset(&self.current_track_position().raw_10ms().to_le_bytes())
            }
            MEDIA_STATE_HANDLE => read_at_offset(&[self.media_state.into()]),
            CONTENT_CONTROL_ID_HANDLE => read_at_offset(&[self.ccid]),
            MEDIA_PLAYER_ICON_URL_HANDLE => {
                let url = self.icon_url.as_ref().ok_or(GattError::InvalidHandle)?;
                read_at_offset(url.as_bytes())
            }
            PLAYBACK_SPEED_HANDLE => {
                let speed = self.playback_speed.ok_or(GattError::InvalidHandle)?;
                read_at_offset(&[speed.into()])
            }
            SEEKING_SPEED_HANDLE => {
                let speed = self.seeking_speed.ok_or(GattError::InvalidHandle)?;
                read_at_offset(&[speed.into()])
            }
            PLAYING_ORDER_HANDLE => {
                let orders = self.playing_orders.as_ref().ok_or(GattError::InvalidHandle)?;
                read_at_offset(&[orders.current.into()])
            }
            PLAYING_ORDERS_SUPPORTED_HANDLE => {
                let orders = self.playing_orders.as_ref().ok_or(GattError::InvalidHandle)?;
                read_at_offset(&orders.supported.bits().to_le_bytes())
            }
            MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE => {
                let opcodes = self.supported_opcodes.ok_or(GattError::InvalidHandle)?;
                read_at_offset(&opcodes.bits().to_le_bytes())
            }
            _ => Err(GattError::InvalidHandle),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use assert_matches::assert_matches;
    use std::time::Duration;

    #[test]
    fn local_state_set_playing_order() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.playing_orders = Some(PlayingOrderState::new(SupportedPlayingOrders::SINGLE_ONCE));
        assert_eq!(state.playing_orders.as_ref().unwrap().current, PlayingOrder::InOrderOnce);

        assert_matches!(state.set_playing_order(PlayingOrder::SingleOnce), Ok(()));
        assert_eq!(state.playing_orders.as_ref().unwrap().current, PlayingOrder::SingleOnce);

        // Unsupported playing order returns Err and is not applied
        assert_matches!(
            state.set_playing_order(PlayingOrder::ShuffleOnce),
            Err(Error::UnsupportedPlayingOrder(PlayingOrder::ShuffleOnce))
        );
        assert_eq!(state.playing_orders.as_ref().unwrap().current, PlayingOrder::SingleOnce);
    }

    #[test]
    fn local_state_handle_read() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.media_state = MediaState::Paused;
        state.playback_speed = Some(PlaybackSpeed::NORMAL);
        state.playing_orders = Some(PlayingOrderState::new(SupportedPlayingOrders::all()));

        // Track Position
        assert_eq!(
            state.handle_read(TRACK_POSITION_HANDLE, 0),
            Ok(TrackPosition::Unavailable.raw_10ms().to_le_bytes().to_vec())
        );

        // Playback Speed
        assert_eq!(state.handle_read(PLAYBACK_SPEED_HANDLE, 0), Ok(vec![0x00]));

        // Playing Order
        assert_eq!(
            state.handle_read(PLAYING_ORDER_HANDLE, 0),
            Ok(vec![PlayingOrder::InOrderOnce.into()])
        );
    }

    #[test]
    fn local_state_track_position_calculation() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.track_duration = TrackDuration::from_raw_10ms(1000);

        // Inactive player always has unavailable track position
        state.media_state = MediaState::Inactive;
        state.track_position = TrackPosition::from_raw_10ms(500);
        assert_eq!(state.current_track_position(), TrackPosition::Unavailable);

        // Paused player returns base track position
        state.media_state = MediaState::Paused;
        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(500));

        // Playing player calculates elapsed time
        state.media_state = MediaState::Playing;
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(2));
        match state.current_track_position() {
            TrackPosition::FromStart(dur) => {
                assert!(dur >= Duration::from_millis(6900) && dur <= Duration::from_millis(7200));
            }
            other => panic!("Expected FromStart duration, got {other:?}"),
        }

        // Clamped to total duration
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(20));
        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(1000));
    }

    #[test]
    fn read_mandatory_characteristics_default_values() {
        let state = McsLocalState::new(0x05, "Test Player");

        assert_eq!(state.handle_read(MEDIA_PLAYER_NAME_HANDLE, 0), Ok(b"Test Player".to_vec()));
        assert_eq!(state.handle_read(TRACK_TITLE_HANDLE, 0), Ok(b"".to_vec()));
        assert_eq!(
            state.handle_read(TRACK_DURATION_HANDLE, 0),
            Ok(TrackDuration::Unknown.raw_10ms().to_le_bytes().to_vec())
        );
        assert_eq!(
            state.handle_read(TRACK_POSITION_HANDLE, 0),
            Ok(TrackPosition::Unavailable.raw_10ms().to_le_bytes().to_vec())
        );
        assert_eq!(state.handle_read(MEDIA_STATE_HANDLE, 0), Ok(vec![MediaState::Inactive.into()]));
        assert_eq!(state.handle_read(CONTENT_CONTROL_ID_HANDLE, 0), Ok(vec![0x05]));
    }

    #[test]
    fn read_optional_characteristics_configured_values() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.icon_url = Some("https://example.com/icon.png".to_string());
        state.playback_speed = Some(PlaybackSpeed::DOUBLE);
        state.seeking_speed = Some(SeekingSpeed::new(10));
        state.playing_orders = Some(PlayingOrderState::new(SupportedPlayingOrders::SHUFFLE_ONCE));
        state.supported_opcodes = Some(SupportedOpcodes::PLAY | SupportedOpcodes::PAUSE);

        assert_eq!(
            state.handle_read(MEDIA_PLAYER_ICON_URL_HANDLE, 0),
            Ok(b"https://example.com/icon.png".to_vec())
        );
        assert_eq!(
            state.handle_read(PLAYBACK_SPEED_HANDLE, 0),
            Ok(vec![PlaybackSpeed::DOUBLE.into()])
        );
        assert_eq!(
            state.handle_read(SEEKING_SPEED_HANDLE, 0),
            Ok(vec![SeekingSpeed::new(10).into()])
        );
        assert_eq!(
            state.handle_read(PLAYING_ORDER_HANDLE, 0),
            Ok(vec![PlayingOrder::InOrderOnce.into()])
        );
        assert_eq!(
            state.handle_read(PLAYING_ORDERS_SUPPORTED_HANDLE, 0),
            Ok(SupportedPlayingOrders::SHUFFLE_ONCE.bits().to_le_bytes().to_vec())
        );
        assert_eq!(
            state.handle_read(MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE, 0),
            Ok((SupportedOpcodes::PLAY | SupportedOpcodes::PAUSE).bits().to_le_bytes().to_vec())
        );
    }

    #[test]
    fn read_string_characteristics_with_offset() {
        let mut state = McsLocalState::new(0x01, "Long Player Name");
        state.track_title = "Track Number 1".to_string();
        state.icon_url = Some("https://example.com".to_string());

        assert_eq!(state.handle_read(MEDIA_PLAYER_NAME_HANDLE, 5), Ok(b"Player Name".to_vec()));
        assert_eq!(state.handle_read(TRACK_TITLE_HANDLE, 6), Ok(b"Number 1".to_vec()));
        assert_eq!(state.handle_read(MEDIA_PLAYER_ICON_URL_HANDLE, 8), Ok(b"example.com".to_vec()));

        assert_matches!(
            state.handle_read(MEDIA_PLAYER_NAME_HANDLE, 100),
            Err(GattError::InvalidOffset)
        );
    }

    #[test]
    fn read_track_position_during_active_playback() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.track_duration = TrackDuration::from_raw_10ms(10000);
        state.media_state = MediaState::Playing;
        state.track_position = TrackPosition::from_raw_10ms(200);
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_millis(500));

        let res = state.handle_read(TRACK_POSITION_HANDLE, 0).expect("read should succeed");
        let raw = i32::from_le_bytes(res.try_into().unwrap());
        assert!(raw >= 240 && raw <= 260, "Expected track position ~250 (10ms units), got {raw}");
    }

    #[test]
    fn read_unconfigured_optional_characteristics_returns_invalid_handle() {
        let state = McsLocalState::new(0x01, "Player");

        let optional_handles = [
            MEDIA_PLAYER_ICON_URL_HANDLE,
            PLAYBACK_SPEED_HANDLE,
            SEEKING_SPEED_HANDLE,
            PLAYING_ORDER_HANDLE,
            PLAYING_ORDERS_SUPPORTED_HANDLE,
            MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE,
        ];

        for handle in optional_handles {
            assert_matches!(
                state.handle_read(handle, 0),
                Err(GattError::InvalidHandle),
                "Handle {:?} should return InvalidHandle when not configured",
                handle
            );
        }
    }

    #[test]
    fn read_non_readable_characteristics_returns_error() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.supported_opcodes = Some(SupportedOpcodes::all());

        assert_matches!(
            state.handle_read(TRACK_CHANGED_HANDLE, 0),
            Err(GattError::ReadNotPermitted)
        );
        assert_matches!(
            state.handle_read(MEDIA_CONTROL_POINT_HANDLE, 0),
            Err(GattError::ReadNotPermitted)
        );
    }

    #[test]
    fn mandatory_characteristics_properties_and_permissions() {
        let mandatory = mandatory_characteristics();
        assert_eq!(mandatory.len(), 7);

        assert_eq!(mandatory[0].handle, MEDIA_PLAYER_NAME_HANDLE);
        assert_eq!(mandatory[0].uuid, MEDIA_PLAYER_NAME_UUID);
        assert_eq!(mandatory[0].properties, CharacteristicProperties::READ_NOTIFY);

        assert_eq!(mandatory[1].handle, TRACK_CHANGED_HANDLE);
        assert_eq!(mandatory[1].uuid, TRACK_CHANGED_UUID);
        assert_eq!(
            mandatory[1].properties,
            CharacteristicProperties::from(CharacteristicProperty::Notify)
        );

        assert_eq!(mandatory[2].handle, TRACK_TITLE_HANDLE);
        assert_eq!(mandatory[2].uuid, TRACK_TITLE_UUID);
        assert_eq!(mandatory[2].properties, CharacteristicProperties::READ_NOTIFY);

        assert_eq!(mandatory[3].handle, TRACK_DURATION_HANDLE);
        assert_eq!(mandatory[3].uuid, TRACK_DURATION_UUID);
        assert_eq!(mandatory[3].properties, CharacteristicProperties::READ_NOTIFY);

        assert_eq!(mandatory[4].handle, TRACK_POSITION_HANDLE);
        assert_eq!(mandatory[4].uuid, TRACK_POSITION_UUID);
        assert_eq!(mandatory[4].properties, CharacteristicProperties::READ_WRITE_NOTIFY);

        assert_eq!(mandatory[5].handle, MEDIA_STATE_HANDLE);
        assert_eq!(mandatory[5].uuid, MEDIA_STATE_UUID);
        assert_eq!(mandatory[5].properties, CharacteristicProperties::READ_NOTIFY);

        assert_eq!(mandatory[6].handle, CONTENT_CONTROL_ID_HANDLE);
        assert_eq!(mandatory[6].uuid, CONTENT_CONTROL_ID_UUID);
        assert_eq!(
            mandatory[6].properties,
            CharacteristicProperties::from(CharacteristicProperty::Read)
        );

        for chrc in &mandatory {
            assert!(chrc.permissions.read.map_or(true, |s| s.encryption));
            assert!(chrc.permissions.write.map_or(true, |s| s.encryption));
            assert!(chrc.permissions.update.map_or(true, |s| s.encryption));
        }
    }

    #[test]
    fn local_state_track_position_calculation_with_playback_speed() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.track_duration = TrackDuration::from_raw_10ms(10000);
        state.media_state = MediaState::Playing;
        state.track_position = TrackPosition::from_raw_10ms(1000); // 10s base

        // Double speed (2.0x): 2s elapsed should add ~4s -> ~14s
        state.playback_speed = Some(PlaybackSpeed::DOUBLE);
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(2));
        match state.current_track_position() {
            TrackPosition::FromStart(dur) => {
                assert!(dur >= Duration::from_millis(13800) && dur <= Duration::from_millis(14200));
            }
            other => panic!("Expected FromStart, got {other:?}"),
        }

        // Half speed (0.5x): 4s elapsed should add ~2s -> ~12s
        state.playback_speed = Some(PlaybackSpeed::HALF);
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(4));
        match state.current_track_position() {
            TrackPosition::FromStart(dur) => {
                assert!(dur >= Duration::from_millis(11800) && dur <= Duration::from_millis(12200));
            }
            other => panic!("Expected FromStart, got {other:?}"),
        }
    }

    #[test]
    fn local_state_track_position_calculation_with_seeking_speed() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.track_duration = TrackDuration::from_raw_10ms(10000); // 100s
        state.media_state = MediaState::Seeking;
        state.track_position = TrackPosition::from_raw_10ms(2000); // 20s base

        // Fast forward (+4x): 2s elapsed should add ~8s -> ~28s
        state.seeking_speed = Some(SeekingSpeed::new(4));
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(2));
        match state.current_track_position() {
            TrackPosition::FromStart(dur) => {
                assert!(dur >= Duration::from_millis(27800) && dur <= Duration::from_millis(28200));
            }
            other => panic!("Expected FromStart, got {other:?}"),
        }

        // Fast rewind (-4x): 2s elapsed should subtract ~8s -> ~12s
        state.seeking_speed = Some(SeekingSpeed::new(-4));
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(2));
        match state.current_track_position() {
            TrackPosition::FromStart(dur) => {
                assert!(dur >= Duration::from_millis(11800) && dur <= Duration::from_millis(12200));
            }
            other => panic!("Expected FromStart, got {other:?}"),
        }

        // Fast rewind saturated at start of track (0s)
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(10));
        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(0));

        // Fast forward clamped at track duration (100s)
        state.seeking_speed = Some(SeekingSpeed::new(4));
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(50));
        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(10000));
    }

    #[test]
    fn local_state_state_transitions_timeline_capture() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.track_duration = TrackDuration::from_raw_10ms(10000);
        state.set_track(
            "Test Track".to_string(),
            TrackDuration::from_raw_10ms(5000),
            TrackPosition::from_raw_10ms(100),
        );
        assert_eq!(state.track_title, "Test Track");
        assert_eq!(state.track_duration, TrackDuration::from_raw_10ms(5000));
        assert_eq!(state.track_position, TrackPosition::from_raw_10ms(100));

        // Transition to Playing
        state.set_media_state(MediaState::Playing);
        assert_eq!(state.media_state, MediaState::Playing);
        assert!(state.position_updated_at.is_some());

        // Fast-forward time simulated: 1s elapsed
        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(1));

        // Transition to Paused: snaps dynamic position
        state.set_media_state(MediaState::Paused);
        assert_eq!(state.media_state, MediaState::Paused);
        match state.track_position {
            TrackPosition::FromStart(dur) => {
                assert!(dur >= Duration::from_millis(1900) && dur <= Duration::from_millis(2200));
            }
            other => panic!("Expected FromStart, got {other:?}"),
        }

        // Transition to Inactive: position unavailable
        state.set_media_state(MediaState::Inactive);
        assert_eq!(state.media_state, MediaState::Inactive);
        assert_eq!(state.track_position, TrackPosition::Unavailable);
        assert!(state.position_updated_at.is_none());

        // Clear track
        state.clear_track();
        assert_eq!(state.track_title, "");
        assert_eq!(state.track_duration, TrackDuration::Unknown);
        assert_eq!(state.track_position, TrackPosition::Unavailable);
    }

    #[test]
    fn local_state_optional_setters_feature_validation() {
        let mut state = McsLocalState::new(0x01, "Player");

        // Unconfigured features return FeatureNotSupported
        assert_matches!(
            state.set_icon_url("https://example.com".to_string()),
            Err(Error::FeatureNotSupported("icon_url"))
        );
        assert_matches!(
            state.set_playback_speed(PlaybackSpeed::NORMAL),
            Err(Error::FeatureNotSupported("playback_speed"))
        );
        assert_matches!(
            state.set_seeking_speed(SeekingSpeed::new(1)),
            Err(Error::FeatureNotSupported("seeking_speed"))
        );
        assert_matches!(
            state.set_playing_order(PlayingOrder::SingleOnce),
            Err(Error::FeatureNotSupported("playing_orders"))
        );
        assert_matches!(
            state.set_supported_opcodes(SupportedOpcodes::all()),
            Err(Error::FeatureNotSupported("media_control_point"))
        );

        // When configured, setters succeed and validate
        state.icon_url = Some(String::new());
        state.playback_speed = Some(PlaybackSpeed::NORMAL);
        state.seeking_speed = Some(SeekingSpeed::NOT_SEEKING);
        state.playing_orders = Some(PlayingOrderState::new(SupportedPlayingOrders::SINGLE_ONCE));
        state.supported_opcodes = Some(SupportedOpcodes::PLAY);

        assert_matches!(state.set_icon_url("https://example.com/icon.png".to_string()), Ok(()));
        assert_eq!(state.icon_url.as_deref(), Some("https://example.com/icon.png"));

        assert_matches!(state.set_playback_speed(PlaybackSpeed::DOUBLE), Ok(()));
        assert_eq!(state.playback_speed, Some(PlaybackSpeed::DOUBLE));

        assert_matches!(state.set_seeking_speed(SeekingSpeed::new(5)), Ok(()));
        assert_eq!(state.seeking_speed, Some(SeekingSpeed::new(5)));

        assert_matches!(state.set_playing_order(PlayingOrder::SingleOnce), Ok(()));
        assert_matches!(
            state.set_playing_order(PlayingOrder::ShuffleOnce),
            Err(Error::UnsupportedPlayingOrder(PlayingOrder::ShuffleOnce))
        );

        assert_matches!(state.set_supported_opcodes(SupportedOpcodes::all()), Ok(()));
    }

    #[test]
    fn seeking_speed_min_boundary_calculation() {
        let mut state = McsLocalState::new(0x01, "Player");
        state.set_track(
            "Song".to_string(),
            TrackDuration::from_raw_10ms(10000),
            TrackPosition::from_raw_10ms(5000),
        );
        state.seeking_speed = Some(SeekingSpeed::new(-128));
        state.set_media_state(MediaState::Seeking);

        // Verify seeking with minimum factor (-128) does not overflow or panic.
        let pos = state.current_track_position();
        match pos {
            TrackPosition::FromStart(dur) => {
                assert!(dur <= Duration::from_millis(50000));
            }
            other => panic!("Expected FromStart, got {other:?}"),
        }

        // Verify FromEnd with Unknown duration resolves to Unavailable per MCS
        // v1.0.1 Section 3.7.1.
        state.set_track(
            "Live Stream".to_string(),
            TrackDuration::Unknown,
            TrackPosition::from_end(Duration::from_secs(10)),
        );
        assert_eq!(state.current_track_position(), TrackPosition::Unavailable);

        // Verify FromEnd with known duration resolves to FromStart(total -
        // end).
        state.set_media_state(MediaState::Paused);
        state.set_track(
            "Track".to_string(),
            TrackDuration::from_raw_10ms(5000), // 50s
            TrackPosition::from_end(Duration::from_secs(10)),
        );
        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(4000));
    }
}
