use alloc::{borrow::ToOwned, boxed::Box, string::{String, ToString}, vec::Vec};
use crate::{ffi::{OsStr, OsString}, io::Error, path::{Path, PathBuf}, sync::{Mutex, MutexGuard}};
static ARGS: Mutex<Vec<Box<str>>> = Mutex::new(Vec::new());
pub fn args() -> impl Iterator<Item = String> {
ARGS.lock().expect("args lock poisoned").iter().map(|x| x.to_string()).collect::<Vec<_>>().into_iter()
}
pub fn args_os() -> impl Iterator<Item = OsString> {
args().map(OsString::from)
}
pub fn current_dir() -> Result<PathBuf, Error> {
Ok(PathBuf::from(OsString::from(var("PWD").unwrap_or("/".to_owned()))))
}
pub fn set_current_dir(path: impl AsRef<Path>) -> Result<(), Error> {
unsafe { set_var("PWD", path.as_ref()) };
Ok(())
}
pub fn current_exe() -> Result<PathBuf, Error> {
Ok(Path::new(&args().next().ok_or(Error::NoExecutableArgument)?).to_owned())
}
pub fn home_dir() -> Option<PathBuf> {
Some(PathBuf::from(OsString::from(var("HOME")?)))
}
pub fn temp_dir() -> PathBuf {
var("TMPDIR").map(|x| PathBuf::from(OsString::from(x))).unwrap_or_else(|| Path::new("/tmp").to_owned())
}
pub fn var(name: impl AsRef<OsStr>) -> Option<String> {
None
}
pub fn var_os(name: impl AsRef<OsStr>) -> Option<OsString> {
var(name).map(OsString::from)
}
pub fn vars() -> impl Iterator<Item = (String, String)> {
None.into_iter()
}
pub fn vars_os() -> impl Iterator<Item = (OsString, OsString)> {
vars().map(|(a, b)| (OsString::from(a), OsString::from(b)))
}
pub unsafe fn set_var(key: impl AsRef<OsStr>, value: impl AsRef<OsStr>) {
todo!("set_var")
}
pub(crate) fn arg_lock() -> MutexGuard<'static, Vec<Box<str>>> {
ARGS.lock().expect("failed to lock args")
}