//! Expose set, block, and format descriptions!
use std::{collections::HashMap, num::NonZeroUsize};

use serde::{Deserialize, Serialize};

pub type SetCode = u16;

#[derive(Debug, Serialize, Deserialize)]
pub struct Set {}

#[derive(Debug, Serialize, Deserialize)]
pub struct Block {}

#[derive(Debug, Serialize, Deserialize)]
pub struct Format {
    metadata: FormatMetadata,
    allowlist: Vec<BlockAllowlist>,
    restrictions: Vec<FormatRestriction>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct FormatMetadata {
    name: String,
    deck_min: NonZeroUsize,
    #[serde(default)]
    deck_max: Option<NonZeroUsize>,
    starting_hand: usize,
    hand_limit: usize,
    #[serde(flatten)]
    metadata: HashMap<String, FormatMetadataValue>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum FormatMetadataValue {
    String(String),
    StringList(Vec<String>),
}

#[derive(Debug, Serialize, Deserialize)]
pub struct BlockAllowlist {}

#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum FormatRestriction {
    Set {
        set: String,
        restriction: Restriction,
    },
    Card {
        set: String,
        set_code: SetCode,
        restriction: Restriction,
    },
}

#[derive(
    Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Copy,
)]
#[serde(rename_all = "snake_case")]
pub enum Restriction {
    /// 0 copies are allowed
    Forbidden,
    /// 1 copy is allowed
    Unique,
    /// 2 copies are allowed
    Restricted,
    /// 3 copies are allowed
    SemiRestricted,
    /// 4 copies are allowed
    #[default]
    Unlimited,
}

#[cfg(test)]
mod tests {
    use assert2::assert;
    #[test]
    fn restriction_order() {
        use super::Restriction::*;
        // This is just to check which way the Ord derive-macro goes
        // This means that they are ordering by number of cards allowed, so
        // Forbidden (0 cards allowed) is less than Unlimited (4 cards allowed)
        assert!(Forbidden < Unlimited);
    }
}