use kithara_platform::{MaybeSend, MaybeSync, time::Duration};

use crate::{
    error::PlayError,
    time::MediaTime,
    types::{ItemStatus, TimeRange},
};

mod kithara {
    pub(crate) use kithara_test_macros::mock;
}

#[kithara::mock(api = PlayerItemMock)]
pub trait PlayerItem: MaybeSend + MaybeSync + 'static {
    fn asset_duration(&self) -> MediaTime;

    fn asset_is_playable(&self) -> bool;

    fn asset_metadata(&self) -> crate::metadata::Metadata;

    fn asset_url(&self) -> Option<url::Url>;

    fn can_play_fast_forward(&self) -> bool;

    fn can_play_reverse(&self) -> bool;

    fn can_step_backward(&self) -> bool;

    fn can_step_forward(&self) -> bool;

    fn cancel_pending_seeks(&self);

    fn current_time(&self) -> MediaTime;

    fn duration(&self) -> MediaTime;

    fn error(&self) -> Option<String>;

    fn is_playback_buffer_empty(&self) -> bool;

    fn is_playback_buffer_full(&self) -> bool;

    fn is_playback_likely_to_keep_up(&self) -> bool;

    fn loaded_time_ranges(&self) -> Vec<TimeRange>;

    fn preferred_forward_buffer_duration(&self) -> Duration;

    fn preferred_peak_bitrate(&self) -> f64;

    fn preferred_peak_bitrate_for_expensive_networks(&self) -> f64;

    fn seek(&self, to: MediaTime) -> Result<(), PlayError>;

    fn seek_with_tolerance(
        &self,
        to: MediaTime,
        tolerance_before: MediaTime,
        tolerance_after: MediaTime,
    ) -> Result<(), PlayError>;

    fn seekable_time_ranges(&self) -> Vec<TimeRange>;

    fn set_preferred_forward_buffer_duration(&self, duration: Duration);

    fn set_preferred_peak_bitrate(&self, bitrate: f64);

    fn set_preferred_peak_bitrate_for_expensive_networks(&self, bitrate: f64);

    fn status(&self) -> ItemStatus;

    fn step_by_count(&self, count: i32);
}

#[cfg(test)]
mod tests {
    use kithara_test_utils::kithara;

    use super::*;

    #[kithara::test]
    fn player_item_mock_api_is_generated() {
        let _ = PlayerItemMock::status;
    }
}
