// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use std::{env, path::{Path, PathBuf}};

use tokio::fs;

use super::FsBase;

#[derive(Clone)]
pub struct Filesystem {
	game_config_base: Box<Path>,
	server_config_user_base: Box<Path>, // Writable by the user
}

impl Filesystem {
	pub async fn try_new() -> Result<Filesystem, String> {
		let (config_home, data_home) = (Self::env("XDG_CONFIG_HOME")?, Self::env("XDG_DATA_HOME")?);
		let game_config_base = config_home.join("spaceships").into_boxed_path();
		let server_config_user_base = data_home.join("spaceships").join("configs").into_boxed_path();

		fs::create_dir_all(&game_config_base).await.map_err(|err| format!("cannot create game config directory: {err}"))?;
		fs::create_dir_all(&server_config_user_base).await.map_err(|err| format!("cannot create user-controlled server config directory: {err}"))?;

		Ok(Filesystem { game_config_base, server_config_user_base })
	}

	fn env(s: &str) -> Result<PathBuf, String> {
		match env::var(s) {
			Ok(path) => Ok(PathBuf::from(path)),
			Err(err) => Err(format!("cannot access {s}, make sure that this binary is being run in Flatpak: {err}")),
		}
	}

	pub fn get(&self, base: FsBase, path: &Path) -> PathBuf {
		match base {
			FsBase::Static => Path::new("/app/data"),
			FsBase::Config => self.game_config_base.as_ref(),
		}.join(path)
	}

	pub fn server_config_dirs(&self) -> Vec<Box<Path>> {
		vec![self.server_config_user_base.clone(), Box::from(Path::new("/app/configs"))]
	}
}
