thesa 4.5.1

Archive repositories, ML models, datasets, websites, free 3D assets, and reusable audio with Scrin/Aisling workflows
use clap::ValueEnum;
use siteforge::ArchiveOutputProfile;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum TuiScreen {
    Mode,
    Provider,
    Target,
    SiteOptions,
    HfToken,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum Mode {
    Repos,
    Models,
    Datasets,
    Sites,
    Assets,
    #[value(alias = "sound", alias = "sounds", alias = "soundforge")]
    Audio,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum RepositoryProvider {
    #[value(alias = "gh")]
    Github,
    #[value(alias = "bb")]
    Bitbucket,
}

impl RepositoryProvider {
    pub(crate) fn label(self) -> &'static str {
        match self {
            Self::Github => "GitHub",
            Self::Bitbucket => "Bitbucket",
        }
    }

    pub(crate) fn manifest_platform(self) -> &'static str {
        match self {
            Self::Github => "github",
            Self::Bitbucket => "bitbucket",
        }
    }
}

impl std::fmt::Display for RepositoryProvider {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.manifest_platform())
    }
}

impl std::fmt::Display for Mode {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Mode::Repos => write!(f, "repos"),
            Mode::Models => write!(f, "models"),
            Mode::Datasets => write!(f, "datasets"),
            Mode::Sites => write!(f, "sites"),
            Mode::Assets => write!(f, "assets"),
            Mode::Audio => write!(f, "audio"),
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum DatasetProvider {
    Hf,
    Zenodo,
}

impl DatasetProvider {
    pub(crate) fn label(self) -> &'static str {
        match self {
            DatasetProvider::Hf => "Hugging Face Datasets",
            DatasetProvider::Zenodo => "Zenodo",
        }
    }

    pub(crate) fn short_label(self) -> &'static str {
        match self {
            DatasetProvider::Hf => "HF",
            DatasetProvider::Zenodo => "ZEN",
        }
    }
}

impl std::fmt::Display for DatasetProvider {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            DatasetProvider::Hf => write!(f, "hf"),
            DatasetProvider::Zenodo => write!(f, "zenodo"),
        }
    }
}

impl From<DatasetProvider> for baseforge::DatasetProvider {
    fn from(value: DatasetProvider) -> Self {
        match value {
            DatasetProvider::Hf => Self::Hf,
            DatasetProvider::Zenodo => Self::Zenodo,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum AssetProvider {
    #[value(alias = "ph")]
    Polyhaven,
    #[value(alias = "acg")]
    Ambientcg,
    #[value(alias = "sf")]
    Sketchfab,
    #[value(
        name = "google-scanned-objects",
        alias = "gso",
        alias = "google",
        alias = "google-objects",
        alias = "scanned-objects",
        alias = "googlescannedobjects"
    )]
    GoogleScannedObjects,
}

impl AssetProvider {
    pub(crate) fn label(self) -> &'static str {
        match self {
            Self::Polyhaven => "Poly Haven",
            Self::Ambientcg => "ambientCG",
            Self::Sketchfab => "Sketchfab CC0",
            Self::GoogleScannedObjects => "Google Scanned Objects",
        }
    }

    pub(crate) fn short_label(self) -> &'static str {
        match self {
            Self::Polyhaven => "PH",
            Self::Ambientcg => "ACG",
            Self::Sketchfab => "SF",
            Self::GoogleScannedObjects => "GSO",
        }
    }
}

impl std::fmt::Display for AssetProvider {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Polyhaven => write!(f, "polyhaven"),
            Self::Ambientcg => write!(f, "ambientcg"),
            Self::Sketchfab => write!(f, "sketchfab"),
            Self::GoogleScannedObjects => write!(f, "google-scanned-objects"),
        }
    }
}

impl From<AssetProvider> for assetforge::AssetProvider {
    fn from(value: AssetProvider) -> Self {
        match value {
            AssetProvider::Polyhaven => Self::PolyHaven,
            AssetProvider::Ambientcg => Self::AmbientCG,
            AssetProvider::Sketchfab => Self::Sketchfab,
            AssetProvider::GoogleScannedObjects => Self::GoogleScannedObjects,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum AudioKind {
    Music,
    #[value(name = "game-audio", alias = "game", alias = "sfx")]
    GameAudio,
    Any,
}

impl AudioKind {
    pub(crate) fn label(self) -> &'static str {
        match self {
            Self::Music => "Music",
            Self::GameAudio => "Game Audio",
            Self::Any => "Any Audio",
        }
    }
}

impl std::fmt::Display for AudioKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Music => write!(f, "music"),
            Self::GameAudio => write!(f, "game-audio"),
            Self::Any => write!(f, "any"),
        }
    }
}

impl From<AudioKind> for soundforge::SoundKind {
    fn from(value: AudioKind) -> Self {
        match value {
            AudioKind::Music => Self::Music,
            AudioKind::GameAudio => Self::GameAudio,
            AudioKind::Any => Self::Any,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum AssetFormat {
    Auto,
    Gltf,
    Fbx,
    Blend,
    Usd,
    Archive,
}

impl std::fmt::Display for AssetFormat {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Auto => write!(f, "auto"),
            Self::Gltf => write!(f, "gltf"),
            Self::Fbx => write!(f, "fbx"),
            Self::Blend => write!(f, "blend"),
            Self::Usd => write!(f, "usd"),
            Self::Archive => write!(f, "archive"),
        }
    }
}

impl From<AssetFormat> for assetforge::AssetFormat {
    fn from(value: AssetFormat) -> Self {
        match value {
            AssetFormat::Auto => Self::Auto,
            AssetFormat::Gltf => Self::Gltf,
            AssetFormat::Fbx => Self::Fbx,
            AssetFormat::Blend => Self::Blend,
            AssetFormat::Usd => Self::Usd,
            AssetFormat::Archive => Self::Archive,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum AssetResolution {
    Auto,
    Original,
    #[value(name = "1k", alias = "1024")]
    OneK,
    #[value(name = "2k", alias = "2048")]
    TwoK,
    #[value(name = "4k", alias = "4096")]
    FourK,
    #[value(name = "8k", alias = "8192")]
    EightK,
}

impl std::fmt::Display for AssetResolution {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Auto => write!(f, "auto"),
            Self::Original => write!(f, "original"),
            Self::OneK => write!(f, "1k"),
            Self::TwoK => write!(f, "2k"),
            Self::FourK => write!(f, "4k"),
            Self::EightK => write!(f, "8k"),
        }
    }
}

impl From<AssetResolution> for assetforge::AssetResolution {
    fn from(value: AssetResolution) -> Self {
        match value {
            AssetResolution::Auto => Self::Auto,
            AssetResolution::Original => Self::Original,
            AssetResolution::OneK => Self::OneK,
            AssetResolution::TwoK => Self::TwoK,
            AssetResolution::FourK => Self::FourK,
            AssetResolution::EightK => Self::EightK,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct SiteTuiOptions {
    pub(crate) full_site: bool,
    pub(crate) max_depth: usize,
    pub(crate) max_pages: usize,
    pub(crate) archive_profile: ArchiveOutputProfile,
    pub(crate) render_js: bool,
    pub(crate) render_js_auto: bool,
}

impl Default for SiteTuiOptions {
    fn default() -> Self {
        Self {
            full_site: true,
            max_depth: 2,
            max_pages: 100,
            archive_profile: ArchiveOutputProfile::Agent,
            render_js: false,
            render_js_auto: false,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum SiteArchiveProfile {
    Full,
    Agent,
    Lean,
}

impl SiteArchiveProfile {
    pub(crate) fn as_output_profile(self) -> ArchiveOutputProfile {
        match self {
            Self::Full => ArchiveOutputProfile::Full,
            Self::Agent => ArchiveOutputProfile::Agent,
            Self::Lean => ArchiveOutputProfile::Lean,
        }
    }
}

impl From<ArchiveOutputProfile> for SiteArchiveProfile {
    fn from(value: ArchiveOutputProfile) -> Self {
        match value {
            ArchiveOutputProfile::Full => Self::Full,
            ArchiveOutputProfile::Agent => Self::Agent,
            ArchiveOutputProfile::Lean => Self::Lean,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum ModelProvider {
    Hf,
    Ollama,
    Civitai,
}

impl ModelProvider {
    pub(crate) fn label(self) -> &'static str {
        match self {
            ModelProvider::Hf => "Hugging Face",
            ModelProvider::Ollama => "Ollama",
            ModelProvider::Civitai => "CivitAI",
        }
    }

    pub(crate) fn short_label(self) -> &'static str {
        match self {
            ModelProvider::Hf => "HF",
            ModelProvider::Ollama => "OLM",
            ModelProvider::Civitai => "CIV",
        }
    }
}

impl std::fmt::Display for ModelProvider {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ModelProvider::Hf => write!(f, "hf"),
            ModelProvider::Ollama => write!(f, "ollama"),
            ModelProvider::Civitai => write!(f, "civitai"),
        }
    }
}

impl From<ModelProvider> for modelforge::ModelProvider {
    fn from(value: ModelProvider) -> Self {
        match value {
            ModelProvider::Hf => Self::Hf,
            ModelProvider::Ollama => Self::Ollama,
            ModelProvider::Civitai => Self::Civitai,
        }
    }
}