//! The MPRIS plugin allows sharing control of media players.
use serde::{Deserialize, Serialize};

#[cfg(not(feature = "std"))]
use alloc::{string::String, vec::Vec};

/// This packet is used for two things: if it contains a playerList field, it is used to enumerate
/// the available media players to a remote device; if it contains a player field, it is used to
/// report the status of a specific media player. Note that player packets can be incremental,
/// ie: only contain the fields that changed since the last update.
///
/// <https://invent.kde.org/network/kdeconnect-meta/blob/master/protocol.md#kdeconnectmpris>
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct MprisPacket {
    /// A list of player names.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub player_list: Option<Vec<String>>,

    /// A player name. This field is used to target a player.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub player: Option<String>,

    /// Can pause.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub can_pause: Option<bool>,

    /// Can play.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub can_play: Option<bool>,

    /// Can go next.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub can_go_next: Option<bool>,

    /// Can go previous.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub can_go_previous: Option<bool>,

    /// Can seek.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub can_seek: Option<bool>,

    /// Whether playback is active.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub is_playing: Option<bool>,

    /// The loop status.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub loop_status: Option<String>,

    /// Whether shuffle is enabled.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub shuffle: Option<bool>,

    /// Current track position (ms).
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub pos: Option<u64>,

    /// Current track album art URL. If it's not an online resource, the receiving device can request the album art as a payload from us (see packet type kdeconnect.mpris.request).
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub album_art_url: Option<String>,

    /// Current track artist.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub artist: Option<String>,

    /// Current track title.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub title: Option<String>,

    /// Current track album.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub album: Option<String>,

    /// Current track length (ms).
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub length: Option<u64>,

    /// Current player volume (%).
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub volume: Option<u8>,

    /// Indicates this device supports album art payloads. This field should be set when responding with a list of players.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub support_album_art_payload: Option<bool>,

    /// Indicates this packet carries an album art payload.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub transferring_album_art: Option<bool>,
}

/// This packet is used to request the status of remote media players, issue commands, and request the transfer of album art payloads.
///
/// <https://invent.kde.org/network/kdeconnect-meta/blob/master/protocol.md#kdeconnectmprisrequest>
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct MprisRequestPacket {
    /// The player name
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub player: Option<String>,

    /// Whether the current status is requested.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub request_now_playing: Option<bool>,

    /// Whether the player list is requested.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub request_player_list: Option<bool>,

    /// Whether the current volume is requested.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub request_volume: Option<bool>,

    /// A request to seek relative to the current position (us). Note the capital S.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    #[serde(rename = "Seek")]
    pub seek: Option<u64>,

    /// A request to set the loop status.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub set_loop_status: Option<String>,

    /// A request to set the track position (ms).
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    #[serde(rename = "SetPosition")]
    pub set_position: Option<u64>,

    /// A request to set the shuffle mode.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub set_shuffle: Option<bool>,

    /// A request to set the player volume.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub set_volume: Option<u64>,

    /// A request to activate a player action.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub action: Option<String>,

    /// A request to transfer the album art payload located at the given URL as a payload.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub album_art_url: Option<String>,
}
