#![feature(const_generics)]

mod common;
mod patch;
use crate::patch::patch::{PatchServerState, PatchTreeIterItem, generate_patch_tree, load_config, load_motd};

fn main() {
    println!("[patch] starting server");

    let patch_config = load_config();
    let patch_motd: String = load_motd();

    if let Err(_) = std::fs::read_dir(patch_config.path.as_str()) {
        println!("Patch directory {} does not exist. Attempting to create it...", patch_config.path.as_str());
        if let Err(err) = std::fs::create_dir(patch_config.path.as_str()) {
            panic!("Failed to create patch directory! \n{}", err);
        }
    }

    let (patch_file_tree, patch_file_lookup) = generate_patch_tree(patch_config.path.as_str());
    println!("[patch] files to patch:");
    let mut indent = 0;
    for item in patch_file_tree.flatten() {
        match item {
            PatchTreeIterItem::Directory(path) => {
                let s = path.to_str().unwrap();
                println!("{: >2$}\u{2517}\u{2500}\u{2500} {}", "", s, indent * 4);
                indent += 1;
            },
            PatchTreeIterItem::File(path, id) => {
                let s = path.to_str().unwrap();
                println!("{: >3$}\u{2520}\u{2500}\u{2500} {} ({})", "", s, id, indent * 4);
            },
            PatchTreeIterItem::UpDirectory => {
                indent -= 1;
            }
        }
    }

    let patch_state = PatchServerState::new(patch_file_tree, patch_file_lookup, patch_motd);
    common::mainloop::mainloop(patch_state, patch_config.port);
    
    println!("[patch] exiting...");
}