pub mod build;
pub mod trips;
pub mod watch;

use fs_extra::dir::{CopyOptions, copy as external_copy_dir};
use regex::Regex;
use std::fs;
use std::path::{Path, PathBuf};
use syntect::highlighting::ThemeSet;
use syntect::html::{ClassStyle, css_for_theme_with_class_style};
use syntect::parsing::SyntaxSet;

use crate::cli::Site;

pub fn write_file(site: Site, path: &str, contents: impl AsRef<[u8]>) {
    let dst = format!("{}/{path}", site.build_dir());
    let mut directory = PathBuf::from(&dst);
    directory.pop();
    fs::create_dir_all(&directory).unwrap();
    fs::write(dst, contents).unwrap();
}

pub fn remove_build_dir(site: Site) {
    let path = Path::new(site.build_dir());
    if path.exists() {
        fs::remove_dir_all(path).unwrap();
    }
}

pub fn copy_dir(site: Site, src: &str, dst: &str) {
    let dst = format!("{}/{dst}", site.build_dir());
    fs::create_dir_all(&dst).ok();
    external_copy_dir(src, &dst, &CopyOptions::new().content_only(true)).unwrap();
}

pub fn french_months(month: &str) -> &'static str {
    match month {
        "01" => "janvier",
        "02" => "février",
        "03" => "mars",
        "04" => "avril",
        "05" => "mai",
        "06" => "juin",
        "07" => "juillet",
        "08" => "août",
        "09" => "septembre",
        "10" => "octobre",
        "11" => "novembre",
        "12" => "décembre",
        _ => panic!("mois invalide: {month}"),
    }
}

pub fn english_months(month: &str) -> &'static str {
    match month {
        "01" => "January",
        "02" => "February",
        "03" => "March",
        "04" => "April",
        "05" => "May",
        "06" => "June",
        "07" => "July",
        "08" => "August",
        "09" => "September",
        "10" => "October",
        "11" => "November",
        "12" => "December",
        _ => panic!("mois invalide: {month}"),
    }
}

pub fn format_meters(distance: f64) -> String {
    if distance > 1500.0 {
        format!("{:.2}km", distance / 1000.0)
    } else {
        format!("{distance:.2}m")
    }
}

pub struct SyntaxHighlighter {
    pub markdown_regexp: Regex,
    pub html_regexp: Regex,
    pub ps: SyntaxSet,
}

impl SyntaxHighlighter {
    pub fn new() -> Self {
        let markdown_regexp = Regex::new(r#"```([a-z]*)\n((.|\s)*?)\n```"#).unwrap();
        let html_regexp =
            Regex::new(r#"<pre><code( class="language-([a-z]*)")?>((.|\s)*?)</code></pre>"#)
                .unwrap();
        let ps = SyntaxSet::load_defaults_newlines();

        let theme = ThemeSet::get_theme("./content/css/verdandi.tmTheme").unwrap();
        let css = css_for_theme_with_class_style(
            &theme,
            ClassStyle::SpacedPrefixed { prefix: "syntect" },
        )
        .unwrap();
        fs::write("./content/css/syntax.css", css).unwrap();

        SyntaxHighlighter {
            markdown_regexp,
            html_regexp,
            ps,
        }
    }
}
