#[macro_use]
extern crate rocket;

use std::fs;
use std::path::PathBuf;
use std::sync::LazyLock;

use rocket::Data;
use rocket::data::ToByteUnit;
use rocket::serde::json::Json;
use rocket::{fs::FileServer, serde::Deserialize};

use rocket_dyn_templates::tera::{Function, Value};
use rocket_dyn_templates::{Template, context, tera};

use dotenv::dotenv;
use serde::Serialize;
use tracing::warn;

use crate::error::ApiError;
use crate::model::{Package, PackageMeta};
use dsx_common::config::DsxConfig;

mod error;
mod model;

mod routes;

fn language_colour() -> impl Function {
    Box::new(
        move |args: &std::collections::HashMap<String, Value>| -> tera::Result<Value> {
            match args.get("lang") {
                Some(Value::String(lang)) => match lang.as_str() {
                    // language syntax colour
                    "dsc" => Ok(Value::String("#000000".to_string())),
                    "dsa" => Ok(Value::String("#3776AB".to_string())),
                    _ => Ok(Value::String("#FFFFFF".to_string())),
                },
                Some(_) => Err(tera::Error::msg("Invalid argument type")),
                None => Ok(Value::String("#FFFFFF".to_string())),
            }
        },
    )
}

#[launch]
fn rocket() -> _ {
    if dotenv().is_err() {
        eprintln!("Failed to load .env file");
    }

    use routes::api;
    use routes::pages;

    rocket::build()
        .mount(
            "/packages",
            routes![
                pages::search_packages,
                pages::package_main,
                pages::repo_file,
                pages::search_repo_files,
                pages::list_artifacts,
                pages::artifact_detail,
            ],
        )
        .mount(
            "/api",
            routes![
                api::create_repo,
                api::get_pkg,
                api::push_tarball,
                api::pull_tarball,
                api::download_artifact
            ],
        )
        .attach(Template::custom(|tera| {
            tera.tera
                .register_function("language_colour", language_colour());
        }))
        .mount("/static", FileServer::from("./static"))
}
