use std::env;
use std::fmt::Display;
use std::process::ExitCode;
use lib::submit_with_name;

fn main() -> ExitCode {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        eprintln!("Usage: main NAME");
        return ExitCode::FAILURE;
    }

    let name = args[1].clone();

    print!("Solving challenge 01_welcome... ");
    let (n, x) = lib::challenges::c1_welcome::solve();
    submit_or_fail(&name, n, x.clone());

    print!("Solving challenge 02_these_numbers_are_big... ");
    let (n, x) = lib::challenges::c2_these_numbers_are_big::solve(&name);
    submit_or_fail(&name, n, x.clone());

    print!("Solving challenge 03_are_you_still_doing_this_by_hand... ");
    let (n, x) = lib::challenges::c3_are_you_still_doing_this_by_hand::solve(n, x);
    submit_or_fail(&name, n, x.clone());

    print!("Solving challenge 04_broken_proof_of_work... ");
    let (n, x) = lib::challenges::c4_broken_proof_of_work::solve(n, x);
    submit_or_fail(&name, n, x.clone());

    print!("Solving challenge 05_what_the_bf... ");
    let (n, x) = lib::challenges::c5_what_the_bf::solve(n, x);
    submit_or_fail(&name, n, x.clone());

    print!("Solving challenge 06_automation_is_not_enough... ");
    let (n, x) = lib::challenges::c6_automation_is_not_enough::solve(n, x);
    submit_or_fail(&name, n, x.clone());

    print!("Solving challenge 07_weird_assembly_machine... ");
    let (n, x) = lib::challenges::c7_weird_assembly_machine::solve(n, x);
    submit_or_fail(&name, n, x.clone());

    println!("n = {n}");
    println!("x = {x}");

    ExitCode::SUCCESS
}

fn submit_or_fail<T1: Display + Send, T2: Display + Send>(name: &str, n: T1, x: T2) {
    match submit_with_name(name, n, x) {
        Ok(_) => println!("Success."),
        Err(err) => println!("Failure: {}", err),
    }
}