//! Embedded builtin image model catalogs (auto-generated by `generate-models image` — do not edit).

use std::collections::HashMap;

use once_cell::sync::Lazy;
use serde::Deserialize;

use crate::types::{ImagesModel, ModelCost};

#[derive(Debug, Deserialize)]
struct RawImageModel {
    id: String,
    name: String,
    api: String,
    provider: String,
    #[serde(rename = "baseUrl")]
    base_url: String,
    input: Vec<String>,
    output: Vec<String>,
    cost: RawCost,
}

#[derive(Debug, Deserialize)]
struct RawCost {
    input: f64,
    output: f64,
    #[serde(rename = "cacheRead")]
    cache_read: f64,
    #[serde(rename = "cacheWrite")]
    cache_write: f64,
}

fn parse_image_models(json: &str) -> Vec<ImagesModel> {
    let raw: HashMap<String, RawImageModel> = serde_json::from_str(json).expect("invalid embedded image model catalog");
    raw.into_values().map(convert_image_model).collect()
}

fn convert_image_model(raw: RawImageModel) -> ImagesModel {
    ImagesModel {
        id: raw.id,
        name: raw.name,
        api: raw.api,
        provider: raw.provider,
        base_url: raw.base_url,
        input: raw.input,
        output: raw.output,
        cost: ModelCost {
            input: raw.cost.input,
            output: raw.cost.output,
            cache_read: raw.cost.cache_read,
            cache_write: raw.cost.cache_write,
        },
        headers: None,
    }
}

macro_rules! define_image_catalog {
    ($name:ident, $file:literal) => {
        pub static $name: Lazy<Vec<ImagesModel>> = Lazy::new(|| {
            parse_image_models(include_str!(concat!(
                env!("CARGO_MANIFEST_DIR"),
                "/models/images/",
                $file
            )))
        });
    };
}

define_image_catalog!(OPENROUTER_IMAGE_MODELS, "openrouter.json");

pub fn all_builtin_image_models() -> HashMap<&'static str, &'static [ImagesModel]> {
    HashMap::from([("openrouter", OPENROUTER_IMAGE_MODELS.as_slice())])
}

pub fn get_builtin_image_models(provider: &str) -> Vec<ImagesModel> {
    all_builtin_image_models()
        .get(provider)
        .map(|models| models.to_vec())
        .unwrap_or_default()
}

pub fn get_builtin_image_providers() -> Vec<&'static str> {
    let mut providers: Vec<_> = all_builtin_image_models().keys().copied().collect();
    providers.sort_unstable();
    providers
}
