mod app;
mod apps;
mod config;
mod logger;
mod proc;
mod result;
mod run;

use std::path::PathBuf;

use log::{info, error};

use apps::Apps;
use config::Config;
use proc::Proc;
use result::Result;
use run::run;

fn main() {
	// config comes from command line arguments
	let config = Config::from_args();

	// logger must be initialized because we use it a bunch
	if let Err(e) = logger::setup(config.log_file, config.log_level) {
		println!("FATAL: Error initializing logger: {:?}", e);
		std::process::exit(1);
	}

	// apps_file is where the applications to start are configured
	let mut apps_file = config.config_directory.clone();
	apps_file.push("apps.toml");

	// start the apps
	match startup(apps_file) {
		Ok(p) => {
			info!("shutting down");
			for mut proc in p {
				proc.stop();
			}
		}
		Err(e) => {
			error!("FATAL: {:?}", e);
			std::process::exit(1);
		}
	};
}

/// Load the apps file and start the apps
fn startup(apps_file: PathBuf) -> Result<Vec<Proc>> {
	let apps = Apps::load(apps_file)?;

	// start all the apps
	let (procs, holds, poll) = apps.start();

	// wait for events
	let procs = run(procs, holds, poll)?;

	Ok(procs)
}