#[macro_use] extern crate rocket;
extern crate chrono;

use rocket::serde::{Serialize, json::Json};

use std::collections::HashMap;


use std::fs::{read_dir};


use std::rc::Rc;

use rocket::fs::FileServer;

use regex::Regex;

const UUID: &'static str = "16f4f9af-ad27-41b7-adae-b0b08bc17b43";
const EMAIL: &'static str = "svaillancourt@add123.com";

#[get("/")]
fn index() -> Json<AddonUpdateListing> {
    let mut result = AddonUpdateListing::new();
    let addon = Addon {
        updates: read_dir("public").unwrap()
            .map(|v| v.unwrap())
            .map(|v| Listing::from_file_name(v.path().to_str().unwrap()))
            .collect()
    };
    let addon = Rc::new(addon);
    result.addons.insert(UUID, Rc::clone(&addon));
    result.addons.insert(EMAIL, addon);

    Json(result)
}

#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
struct AddonUpdateListing {
    addons: HashMap<&'static str, Rc<Addon>>
}

impl AddonUpdateListing {
    pub fn new() -> Self {
        Self {
            addons: HashMap::new()
        }
    }
}

#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
struct Addon {
    updates: Vec<Listing>
}

#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
struct Listing {
    version: String,
    update_link: String
}

impl Listing {
    pub fn from_file_name(file_name: &str) -> Self {
        let r = Regex::new(r#"public/([^0-9]+([0-9.]+)\..*)"#).unwrap();
        let name_match = r.captures(file_name).unwrap();
        let file_name = name_match.get(1).unwrap().as_str();
        Self {
            version: name_match.get(2).unwrap().as_str().to_string(),
            update_link: format!("https://bb-addon.sagev.space/{file_name}")
        }
    }
}

#[launch]
fn rocket() -> _ {
    rocket::build()
        .mount("/updates.json", routes![index])
        .mount("/", FileServer::from("public"))
}

