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