mod cli;
mod server;

use anyhow::Result;
use clap::{Parser, Subcommand};

/// adom-chipsmith — STEP-native chip detection + footprint validation + sign-off.
///
/// Loads a .step file (alongside its .kicad_mod footprint, datasheet PDF, and
/// chipsmith-spec.json manifest), reads the STEP's B-rep + assembly hierarchy
/// directly via service-step2glb's `/step-meta` endpoint (NOT the GLB triangle
/// mesh), runs detection in three modes (named PRODUCT walk → surface-type
/// cluster → face-merge fallback), validates measurements, auto-recovers from
/// Y-up vs Z-up, detects pin-1 on both chip and footprint, layers a 1.6mm faux
/// PCB + heatsink vias + solder-jet domes, and on user sign-off bakes a
/// `<mpn>.chipsmith.step` (canonical) + shadow `.chipsmith.glb` + sidecar JSON.
///
/// Every UI verb has a JS API helper, an HTTP endpoint, and a CLI subcommand
/// so an AI agent can drive the validator headlessly.
///
/// See PLAN.md for the full spec.
#[derive(Parser)]
#[command(name = "adom-chipsmith", version, about, long_about = None)]
struct Cli {
    #[command(subcommand)]
    command: Command,
}

#[derive(Subcommand)]
enum Command {
    /// Open a chip in the Hydrogen webview tab. Loads the STEP via
    /// service-step2glb (cached on disk by content hash) and pulls the
    /// step-meta sidecar so detection can run on B-rep data.
    View(cli::view::Args),
    /// Open a chip from a chip-fetcher library directory. Pulls the .step,
    /// .kicad_mod footprint, datasheet PDF, and info.json manifest from
    /// `<chip-fetcher>/library/<MPN>/`.
    ViewLibrary(cli::view_library::Args),
    /// Stop a running adom-chipsmith server on the given port.
    Stop(cli::stop::Args),
    /// Print status of the running adom-chipsmith server.
    Status(cli::status::Args),
    /// Re-attach the webview tab without restarting the server.
    Open(cli::open::Args),
    /// Health check against a running server.
    Health(cli::health::Args),
    /// Install binary to ~/.local/bin/, drop SKILL.md, install completions.
    Install(cli::install::Args),
    /// Print the discovered scene-graph component tree (one row per node).
    ListComponents(cli::list_components::Args),
    /// Hide every other top-level subtree and frame the camera on the named node.
    Isolate(cli::isolate::Args),
    /// Show the named node (and its descendants).
    Show(cli::show::Args),
    /// Hide the named node (and its descendants).
    Hide(cli::hide::Args),
    /// Show all nodes (clear visibility overrides).
    ShowAll(cli::show_all::Args),
    /// Frame the camera on a named node, or the whole model when omitted.
    Frame(cli::frame::Args),
    /// Save a PNG screenshot of the current canvas.
    Screenshot(cli::screenshot::Args),
    /// Run a JavaScript snippet inside the webview and print its result.
    Eval(cli::eval::Args),
    /// Print the JavaScript console log forwarded from the webview.
    Console(cli::console::Args),
    /// Reveal a file in the VS Code Explorer sidebar (delegates to adom-vscode).
    Reveal(cli::reveal::Args),
    /// Run detection headlessly on a chip-fetcher dir and print a JSON report.
    Detect(cli::detect::Args),
    /// Place a synthetic pin-1 indicator (corner / fp-marker / xy click).
    PlacePin1(cli::place_pin1::Args),
    /// Toggle a chipsmith overlay layer (footprint / stock / faux-pcb / heatsink / solderjet).
    SetOverlay(cli::set_overlay::Args),
    /// Sign off the loaded chip — writes <mpn>.chipsmith.json + bakes <mpn>.chipsmith.step.
    SignOff(cli::sign_off::Args),
    /// Kill → optional rebuild → restart server → reload pup browser. One command.
    Restart(cli::restart::Args),
}

fn main() -> Result<()> {
    let cli = Cli::parse();
    match cli.command {
        Command::View(a) => cli::view::run(a),
        Command::ViewLibrary(a) => cli::view_library::run(a),
        Command::Stop(a) => cli::stop::run(a),
        Command::Status(a) => cli::status::run(a),
        Command::Open(a) => cli::open::run(a),
        Command::Health(a) => cli::health::run(a),
        Command::Install(a) => cli::install::run(a),
        Command::ListComponents(a) => cli::list_components::run(a),
        Command::Isolate(a) => cli::isolate::run(a),
        Command::Show(a) => cli::show::run(a),
        Command::Hide(a) => cli::hide::run(a),
        Command::ShowAll(a) => cli::show_all::run(a),
        Command::Frame(a) => cli::frame::run(a),
        Command::Screenshot(a) => cli::screenshot::run(a),
        Command::Eval(a) => cli::eval::run(a),
        Command::Console(a) => cli::console::run(a),
        Command::Reveal(a) => cli::reveal::run(a),
        Command::Detect(a) => cli::detect::run(a),
        Command::PlacePin1(a) => cli::place_pin1::run(a),
        Command::SetOverlay(a) => cli::set_overlay::run(a),
        Command::SignOff(a) => cli::sign_off::run(a),
        Command::Restart(a) => cli::restart::run(a),
    }
}