// Utility functions for the static site generator

// Escape HTML special characters
pub fn escapeHtml(s: String): String =
    String.replace(String.replace(String.replace(s, "&", "&amp;"), "<", "&lt;"), ">", "&gt;")

// Extract slug from a filename like "2025-01-29-blog-revamped.md"
// Returns "2025-01-29-blog-revamped"
pub fn slugFromFilename(filename: String): String = {
    if String.endsWith(filename, ".md") then
        String.substring(filename, 0, String.length(filename) - 3)
    else
        filename
}

// Format ISO date "2025-01-29" to "2025 Jan 29"
pub fn formatDate(isoDate: String): String = {
    if String.length(isoDate) < 10 then isoDate
    else {
        let year = String.substring(isoDate, 0, 4);
        let month = String.substring(isoDate, 5, 7);
        let day = String.substring(isoDate, 8, 10);
        let monthName = if month == "01" then "Jan"
            else if month == "02" then "Feb"
            else if month == "03" then "Mar"
            else if month == "04" then "Apr"
            else if month == "05" then "May"
            else if month == "06" then "Jun"
            else if month == "07" then "Jul"
            else if month == "08" then "Aug"
            else if month == "09" then "Sep"
            else if month == "10" then "Oct"
            else if month == "11" then "Nov"
            else "Dec";
        year + " " + monthName + " " + day
    }
}

// Recursively walk a directory, returning all file paths
pub fn walkDir(path: String): List<String> with {File} = {
    let entries = File.readDir(path);
    List.fold(entries, [], fn(acc: List<String>, entry: String): List<String> => {
        let fullPath = path + "/" + entry;
        if File.isDir(fullPath) then
            List.concat(acc, walkDir(fullPath))
        else
            List.concat(acc, [fullPath])
    })
}

// Insertion sort by date string (descending — newest first)
// Each item is (date, item) tuple
pub fn sortByDateDesc(items: List<(String, String, String, String, String)>): List<(String, String, String, String, String)> = {
    List.fold(items, [], fn(sorted: List<(String, String, String, String, String)>, item: (String, String, String, String, String)): List<(String, String, String, String, String)> =>
        insertByDate(sorted, item)
    )
}

fn insertByDate(sorted: List<(String, String, String, String, String)>, item: (String, String, String, String, String)): List<(String, String, String, String, String)> = {
    let itemDate = item.0;
    match List.head(sorted) {
        None => [item],
        Some(first) => {
            let firstDate = first.0;
            // Compare dates as strings — ISO format sorts lexicographically
            if itemDate >= firstDate then
                List.concat([item], sorted)
            else
                match List.tail(sorted) {
                    Some(rest) => List.concat([first], insertByDate(rest, item)),
                    None => [first, item]
                }
        }
    }
}

// Get just the filename from a path
pub fn basename(path: String): String = {
    match String.lastIndexOf(path, "/") {
        Some(idx) => String.substring(path, idx + 1, String.length(path)),
        None => path
    }
}

// Get the directory part of a path
pub fn dirname(path: String): String = {
    match String.lastIndexOf(path, "/") {
        Some(idx) => String.substring(path, 0, idx),
        None => "."
    }
}
