use crate::cli::CliError;
use serde::Deserialize;
use std::{env, fs, io::ErrorKind};

#[derive(Debug, Deserialize, Clone)]
pub struct Model {
	pub h5_file: String,
	pub json_path: String,
	pub parameters: Vec<String>,
}

#[derive(Debug, Deserialize, Clone)]
pub struct Config {
	pub api_key: String,
}

#[derive(Debug, Deserialize, Clone)]
pub struct RezonConfig {
	pub config: Config,
	pub model: Model,
}

impl RezonConfig {
	/**
	 * Note: A side effect of this function is that it may find a rezon.toml in a parent directory when running
	 * from a directory that has not been initialized with rezon. Best solution is to adhere to principle of
	 * least astonishment and document this behavior.
	 */
	pub fn read_config() -> Result<RezonConfig, CliError<'static>> {
		let mut path = env::current_dir().unwrap();
		loop {
			let candidate = path.join("rezon.toml");
			if candidate.exists() {
				let contents = fs::read_to_string(&candidate).map_err(|err| match err.kind() {
					ErrorKind::PermissionDenied => CliError::new("Permission denied when reading rezon.toml", 64),
					_ => CliError::new("An unknown error occurred when reading rezon.toml", 64),
				})?;

				let rezon_config: RezonConfig = toml::from_str(&contents).map_err(|err| {
					eprintln!("{:?}", err);
					CliError::new("Failed to parse the config file", 200)
				})?;

				return Ok(rezon_config);
			}
			if !path.pop() {
				break;
			}
		}

		Err(CliError::new("Could not find a valid config file in the current working directory. Please make sure you are in a project scaffolded with the Rezon CLI.", 64))
	}

	pub fn find() -> Result<RezonConfig, CliError<'static>> {
		Self::read_config()
	}
}
