use crate::{FunctionModule, FunctionSpec, module::register_fn};
use roto::{Type, Val};
use std::cell::RefCell;
use std::sync::Arc;

#[derive(Clone, Debug)]
pub struct LocalTempFile {
    pub path: Arc<str>,
}

thread_local! {
    static CURRENT_TEMP_FILES: RefCell<Vec<Arc<str>>> = const { RefCell::new(Vec::new()) };
}

pub fn module() -> FunctionModule {
    FunctionModule::builder("fs")
        .doc("Local filesystem utilities.")
        .function(FunctionSpec::new(
            "fs",
            "create_tempfile",
            "Create a temporary file and return its handle.",
            vec![],
            "LocalTempFile",
        ))
        .on_close(|| {
            CURRENT_TEMP_FILES.with(|files| {
                for path in files.borrow_mut().drain(..) {
                    let _ = std::fs::remove_file(path.as_ref());
                }
            });
            Ok(())
        })
        .build(|runtime, _params| {
            let t = Type::clone::<Val<LocalTempFile>>(
                "LocalTempFile",
                "A handle to a local temporary file",
                roto::location!(),
            )
            .unwrap();
            runtime.add(t).unwrap();

            register_fn(
                runtime,
                "fs_create_tempfile",
                "Create a temp file.",
                &[],
                || -> Val<LocalTempFile> {
                    let nanos = std::time::SystemTime::now()
                        .duration_since(std::time::UNIX_EPOCH)
                        .unwrap()
                        .as_nanos();
                    let path: Arc<str> = format!("/tmp/roto_fs_{}", nanos).into();
                    CURRENT_TEMP_FILES.with(|files| {
                        files.borrow_mut().push(path.clone());
                    });
                    Val(LocalTempFile { path })
                },
            )
        })
}
