use crate::prelude::*;

pub fn get_config_file_path(name: &str) -> IoResult<PathBuf> {
	let bd = xdg::BaseDirectories::new()?;
	bd.place_config_file(format!("porthole/{name}"))
}

pub fn read_password(prompt: &str) -> IoResult<String> {
	let password = rpassword::prompt_password(prompt)?;

	Ok(password)
}

pub fn read_matching_passwords() -> IoResult<String> {
	loop {
		let password = read_password("Password: ").unwrap();
		let confirm_password = read_password("Confirm password: ").unwrap();

		if password == confirm_password {
			return Ok(password);
		} else {
			println!("Passwords did not match")
		}
	}
}

pub fn prompt<T: std::str::FromStr>(prompt: &str) -> IoResult<T>
where
	<T as FromStr>::Err: Debug,
{
	let mut stdin = std::io::stdin().lock();

	loop {
		print!("{}", prompt);
		std::io::stdout().flush()?;
		let mut s = String::new();
		stdin.read_line(&mut s)?;
		let parsed = match s.trim().parse() {
			Ok(v) => v,
			Err(e) => {
				println!("{e:?}");
				continue;
			},
		};

		return Ok(parsed);
	}
}

pub fn random_string(len: usize) -> String {
	use rand::Rng;

	rand::rng()
		.sample_iter(&rand::distr::Alphanumeric)
		.take(len)
		.map(char::from)
		.collect()
}

pub fn hash_password(password: &str) -> (String /* Hash */, String /* Salt */) {
	let config = argon2::Config::default();
	let salt = random_string(16);

	let hash =
		argon2::hash_encoded(password.as_bytes(), salt.as_bytes(), &config)
			.unwrap();

	(hash, salt)
}
