//! npm package manager parser (#105)
//!
//! Parses `npm install`, `npm audit`, `npm outdated`, `npm ls`, `npm test`,
//! and `npm run` output using three-tier degradation: JSON -> regex -> passthrough.
//!
//! `npm test` and `npm run` detect the underlying tool from `package.json`
//! and delegate to the matching parser (vitest, jest, eslint, etc.).
//!
//! npm 7+ JSON schemas are supported. If JSON fails to parse, tier 2 regex
//! is attempted on plain text output.

mod audit;
mod install;
mod ls;
mod outdated;
mod run;
mod script_tool;

use std::process::ExitCode;

// Re-exported from parent so submodules can access via `super::`.
use super::{PkgSubcommandConfig, combine_output, run_pkg_subcommand};

/// Run `skim npm <subcmd> [args...]`.
///
/// Sub-dispatches to install, audit, outdated, or ls based on the first arg.
pub(crate) fn run(
    args: &[String],
    show_stats: bool,
    json_output: bool,
    rec: crate::analytics::RecordingContext<'_>,
) -> anyhow::Result<ExitCode> {
    if args.is_empty() || args.iter().any(|a| matches!(a.as_str(), "--help" | "-h")) {
        print_help();
        return Ok(ExitCode::SUCCESS);
    }

    // Safe: args.is_empty() is handled above.
    let (subcmd, subcmd_args) = args.split_first().expect("already verified non-empty");

    match subcmd.as_str() {
        "install" | "i" | "ci" => install::run_install(subcmd_args, show_stats, json_output, rec),
        "audit" => audit::run_audit(subcmd_args, show_stats, json_output, rec),
        "outdated" => outdated::run_outdated(subcmd_args, show_stats, json_output, rec),
        "ls" | "list" => ls::run_ls(subcmd_args, show_stats, json_output, rec),
        "test" | "t" => run::run_script("test", subcmd_args, show_stats, json_output, rec),
        "run" | "run-script" => run::run_script("run", subcmd_args, show_stats, json_output, rec),
        other => {
            let safe = crate::cmd::sanitize_for_display(other);
            eprintln!(
                "skim npm: unknown subcommand '{safe}'\n\
                 Available: install, audit, outdated, ls, test, run\n\
                 Run 'skim npm --help' for usage"
            );
            Ok(ExitCode::FAILURE)
        }
    }
}

fn print_help() {
    println!("skim npm <subcmd> [args...]");
    println!();
    println!("  Parse npm output for AI context windows.");
    println!();
    println!("Subcommands:");
    println!("  install    Parse npm install output");
    println!("  audit      Parse npm audit output");
    println!("  outdated   Parse npm outdated output");
    println!("  ls         Parse npm ls output");
    println!("  test (t)   Run npm test with tool-detected output compression");
    println!("  run        Run npm run <script> with tool-detected output compression");
    println!();
    println!("Examples:");
    println!("  skim npm install");
    println!("  skim npm audit");
    println!("  skim npm outdated");
    println!("  skim npm ls");
    println!("  skim npm test");
    println!("  skim npm run lint");
    println!("  npm install 2>&1 | skim npm install");
}
