// 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::*;

// ============================================================================
// 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;
        }

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

        // Playback is paused or seeking, so the position remains fixed at the current
        // offset.
        if self.media_state != MediaState::Playing {
            return self.track_position;
        }

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

        // TODO(b/540400364): Factor in optional playback speed when supported
        let mut current = base + updated_at.elapsed();
        if let TrackDuration::Duration(total) = self.track_duration {
            current = current.min(total);
        }
        TrackPosition::FromStart(current)
    }

    /// Sets the track position and records the update timestamp.
    pub(crate) fn set_track_position(&mut self, position: TrackPosition) {
        self.track_position = position;
        self.position_updated_at = Some(std::time::Instant::now());
    }

    /// Sets the playback speed.
    pub(crate) fn set_playback_speed(&mut self, speed: PlaybackSpeed) {
        self.playback_speed = Some(speed);
    }

    /// Sets the playing order if playing order is supported.
    pub(crate) fn set_playing_order(&mut self, order: PlayingOrder) {
        if let Some(ref mut orders) = self.playing_orders {
            if orders.supported.contains(order.into()) {
                orders.current = order;
            }
        }
    }

    #[cfg(test)]
    pub(crate) fn set_media_state(&mut self, state: MediaState) {
        self.media_state = state;
    }

    #[cfg(test)]
    pub(crate) fn set_supported_opcodes(&mut self, opcodes: SupportedOpcodes) {
        self.supported_opcodes = Some(opcodes);
    }

    /// 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);

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

        // Unsupported playing order is not applied
        state.set_playing_order(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));
        }
    }
}
