use std::io::Write;

use idl::build_idl;
pub mod idl;

pub enum Options {
    Build,
    Clean,
    New,
    Run,
}
#[derive(PartialEq, Debug)]
pub enum DevelopmentType {
    Program,
    Library,
    IDL,
}

fn main() {
    let mut args: Vec<String> = std::env::args().collect();
    args.remove(0);
    args.reverse();

    let binding = args.pop().unwrap_or("help".to_string());
    let subcommand = binding.as_str();

    match subcommand {
        "build" => {
            let name = &args.pop().unwrap();
            build(name.to_string())
        }
        "new" => {
            let binding = args.pop().unwrap();
            let dev_type = binding.as_str();
            let name = args.pop().unwrap();
            use DevelopmentType::*;
            match dev_type {
                "lib" | "library" => new(Library, name),
                "prog" | "program" => new(Program, name),
                "idl" => {
                    new(IDL, name);
                    // idl::main();
                    panic!("IDL is not finalized yet.")
                }
                _ => {}
            };
        }
        "run" => run(),
        "help" => help(),
        _ => {
            println!("Error");
        }
    }
}

pub fn new(development_type: DevelopmentType, name: String) {
    let (folder_hierarchy, entry_name) = match development_type {
        DevelopmentType::Program => ("programs", "main.hb"),
        DevelopmentType::Library => ("libraries", "lib.hb"),
        DevelopmentType::IDL => ("idl", "protocol.aidl"),
    };
    let project_folder_path_string = format!("sysdata/{folder_hierarchy}/{name}");

    if std::path::Path::new(&project_folder_path_string).exists() {
        panic!("Project already exists.")
    }

    std::fs::create_dir(project_folder_path_string.clone()).unwrap();
    let readme_path_string = format!("{}/README.md", project_folder_path_string);
    let mut readme_file = std::fs::File::create(readme_path_string.clone()).unwrap();

    let readme_contents = format!("# {}", name);
    readme_file.write_all(readme_contents.as_bytes()).unwrap();

    let contents = format!(
        "[package]
name = \"{}\"
authors = [\"\"]

[dependants.libraries]

[dependants.binaries]
hblang.version = \"1.0.0\"

[build]
command = \"hblang src/main.hb\"
",
        name
    );

    let toml_path_string = format!("{}/meta.toml", project_folder_path_string);
    let mut readme_file = std::fs::File::create(toml_path_string.clone()).unwrap();

    readme_file.write_all(contents.as_bytes()).unwrap();

    let src_folder_path_string = format!("{}/src", project_folder_path_string);
    std::fs::create_dir(src_folder_path_string.clone()).unwrap();

    let full_path_string = format!("{src_folder_path_string}/{entry_name}");
    let mut file = std::fs::File::create(full_path_string.clone()).unwrap();
    let file_contents = match development_type {
        DevelopmentType::Program => "main := fn(): int {
    return 0
}"
        .to_string(),
        DevelopmentType::Library => "".to_string(),
        DevelopmentType::IDL => format!(
            "protocol {} {{
}}",
            name
        )
        .to_owned(),
    }
    .to_string();
    file.write_all(file_contents.as_bytes()).unwrap();

    println!("New project created.");
    if development_type == DevelopmentType::Program {
        println!("You should add your project into the ableOS system configuration in sysdata/system_config.toml")
    }
}

fn run() {
    println!("Running is not supported on a non-ableOS platform");
}

fn build(name: String) {
    println!("building {}", name);
    let mut a = name.split("/");
    let dev_type = a.next().unwrap();
    let name = a.next().unwrap().to_string();
    match dev_type {
        "programs" => build_program(name),
        "idl" => build_idl(name),
        _ => {
            panic!()
        }
    }
}

pub fn build_program(name: String) {}
pub fn build_library(name: String) {}

fn help() {
    println!(
        "==========
=  Help  =
==========
Subcommands
- new  Usage: `cargo dev new library name` or `cargo dev new program name`"
    )
}