use std::{fs, path::PathBuf};

use clap::{Parser, Subcommand};
use config::{CliConfigs, Config};
use dev::DevCommands;
use welcome_msg::print_startup_msg;

mod config;

#[allow(unused)]
mod error_reporting;
mod welcome_msg;

#[derive(Parser)]
struct Args {
    #[command(flatten)]
    configs: CliConfigs,
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    Run {
        /// What file contains the pipeline to evaluate.
        source: PathBuf,
    },
    Dev {
        #[command(subcommand)]
        command: DevCommands,
    },
}

fn main() {
    // TODO: proper error handling across the whole function
    //       don't forget to also look inside `Config`
    let args = Args::parse();
    let cfg = Config::read(&args.configs);

    if cfg.startup_msg {
        print_startup_msg();
    }

    match args.command {
        Commands::Run { source } => {
            let source = fs::read_to_string(source).expect("can't find source file");
            let ir = ir::from_ron(&source).expect("failed to parse source to graph ir");

            let mut machine = cfg.evaluator.pick();
            machine.feed(ir);
            machine.eval_full();
        }
        Commands::Dev {
            command: dev_command,
        } => dev_command.run(),
    }
}

mod dev {
    use clap::Subcommand;

    #[derive(Subcommand)]
    pub(crate) enum DevCommands {}

    impl DevCommands {
        pub fn run(self) {
            println!("There are currently no dev commands.");
        }
    }
}
