use serde::Serialize;

#[derive(Debug, Clone, Serialize)]
pub struct NameReport {
    pub name: String,
    pub results: Vec<CheckResult>,
}

#[derive(Debug, Clone, Serialize)]
pub struct CheckResult {
    pub source: String,
    pub status: Status,
}

#[derive(Debug, Clone, Serialize)]
#[serde(tag = "state", rename_all = "lowercase")]
pub enum Status {
    Free,
    Taken(Box<TakenInfo>),
    Unknown { reason: String },
}

#[derive(Debug, Clone, Default, Serialize)]
pub struct TakenInfo {
    pub version: Option<String>,
    pub description: Option<String>,
    pub owner: Option<String>,
    pub downloads: Option<u64>,
    pub recent_downloads: Option<u64>,
    pub last_release: Option<String>,
    pub classification: Classification,
}

#[derive(Debug, Clone, Copy, Default, Serialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum Classification {
    /// Recently released with real download activity.
    Active,
    /// v0.0.x stub with no downloads, typical name squat.
    Placeholder,
    /// Released once long ago, no recent activity.
    Dead,
    /// Cannot determine from available metadata.
    #[default]
    Unknown,
}

impl Classification {
    pub fn label(self) -> &'static str {
        match self {
            Self::Active => "ACTIVE",
            Self::Placeholder => "PLACEHOLDER",
            Self::Dead => "DEAD",
            Self::Unknown => "UNKNOWN",
        }
    }
}
