// r8r: rust port of n8n.io
// Initial author: Michael Cochran <mcochran@cochranblock.org>
// Built for: Tanner Woodrum, intended cofounder
// License: Unlicense (public domain dedication, see UNLICENSE)

use anyhow::Result;
use clap::Parser;
use r8r::codegen::{emit, extract};
use std::path::PathBuf;
use tracing::{info, warn};

#[derive(Parser)]
#[command(name = "r8r-codegen", about = "Walk an n8n source tree and emit Rust node skeletons")]
struct Cli {
    /// Path to a cloned n8n source tree (the directory containing packages/)
    n8n_root: PathBuf,

    /// Where to drop the per-node JSON specs
    #[arg(long, default_value = "nodes-spec")]
    spec_dir: PathBuf,

    /// Where to drop the generated .rs stubs
    #[arg(long, default_value = "src/nodes/generated")]
    out_dir: PathBuf,
}

fn main() -> Result<()> {
    tracing_subscriber::fmt::init();
    let cli = Cli::parse();
    let files = extract::discover_node_files(&cli.n8n_root);
    info!(count = files.len(), "discovered .node.ts files");

    let mut specs = Vec::with_capacity(files.len());
    for path in &files {
        match extract::extract_one(path, &cli.n8n_root) {
            Ok(s) => specs.push(s),
            Err(e) => warn!(path = %path.display(), error = %e, "extract failed"),
        }
    }

    let mut seen = std::collections::HashSet::new();
    specs.retain(|s| seen.insert(s.slug()));
    info!(unique = specs.len(), "deduped specs");

    for spec in &specs {
        emit::emit_spec_json(spec, &cli.spec_dir)?;
        emit::emit_rust_stub(spec, &cli.out_dir)?;
    }
    emit::emit_mod_rs(&specs, &cli.out_dir)?;
    info!("emit complete");
    Ok(())
}
