use kithara_platform::{MaybeSend, MaybeSync, tokio::sync::broadcast};

#[rustfmt::skip]
use crate::traits::item::PlayerItem;
use crate::{events::PlayerEvent, types::SlotId};

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

#[kithara::mock(api = QueuePlayerMock, type Item = unimock::Unimock;)]
pub trait QueuePlayer: MaybeSend + MaybeSync + 'static {
    type Item: PlayerItem;

    fn advance_to_next_item(&self);

    fn can_insert(&self, item: &Self::Item, after: Option<&Self::Item>) -> bool;

    fn current_item(&self) -> Option<&Self::Item>;

    fn insert(&self, item: Self::Item, after: Option<&Self::Item>);

    fn items(&self) -> Vec<&Self::Item>;

    fn pause(&self);

    fn play(&self);

    fn remove(&self, item: &Self::Item);

    fn remove_all_items(&self);

    fn slot_id(&self) -> Option<SlotId>;

    fn subscribe(&self) -> broadcast::Receiver<PlayerEvent>;
}

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

    use super::*;

    fn assert_queue_item_unimock<T: QueuePlayer<Item = Unimock>>() {}

    #[kithara::test]
    fn queue_player_mock_api_is_generated() {
        let _ = QueuePlayerMock::items;
    }

    #[kithara::test]
    fn queue_player_unimock_item_is_unimock() {
        assert_queue_item_unimock::<Unimock>();
    }
}
