use std::process::Command;

use crate::ExtensionTarget;

#[derive(Debug, clap::Parser)]
pub struct Args {
    #[arg(value_enum)]
    extension_target: ExtensionTarget,
}

impl Args {
    pub fn run(&self, metadata: &cargo_metadata::Metadata) -> Result<(), anyhow::Error> {
        let base_path = self.extension_target.base_path(metadata);

        // TODO: walk the tree before/after build to make sure no artifacts were missed
        match self.extension_target {
            ExtensionTarget::VisualStudioCode => {
                // Steps:
                // 1. Install all dependencies
                // 2. Build native Rust module
                // 3. Build TypeScript code

                let out_dir = base_path.join("out");
                let native_module = out_dir.join("native-module");
                std::fs::create_dir_all(&out_dir)?;
                std::fs::create_dir_all(&native_module)?;

                // TODO: pnpm install?
                // TODO: release builds
                // TODO: multiple targets
                let mut rust_build = Command::new("pnpm");
                rust_build.current_dir(&base_path);
                rust_build.args([
                    "exec",
                    "napi",
                    "build",
                    "--platform",
                    "--output-dir",
                    native_module.as_str(),
                    "--target",
                    "x86_64-unknown-linux-gnu",
                ]);
                let rust_exit_status = rust_build.status()?;
                assert!(rust_exit_status.success());

                let mut typescript_build = Command::new("pnpm");
                typescript_build.current_dir(base_path);
                typescript_build.args(["exec", "tsc", "--outDir", out_dir.as_str()]);
                let typescript_exit_status = typescript_build.status()?;
                assert!(typescript_exit_status.success());
            }
        }

        Ok(())
    }
}