//! Integration tests for `mcptest ecosystem` (WOR-1427).
//!
//! The command is offline: it reads source files, normalizes them into a
//! corpus manifest, and selects fixture packs. These tests drive the built
//! binary against the committed `examples/ecosystem` sample data.

use std::path::PathBuf;

use assert_cmd::Command;
use predicates::prelude::*;

fn mcptest() -> Command {
    Command::cargo_bin("mcptest").expect("binary builds")
}

fn sample(name: &str) -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .join("../../examples/ecosystem")
        .join(name)
}

#[test]
fn import_emits_a_corpus_with_stable_hash() {
    let dir = tempfile::tempdir().unwrap();
    let out = dir.path().join("corpus.json");
    mcptest()
        .args(["ecosystem", "import", "--mcpcorpus"])
        .arg(sample("mcpcorpus-sample.json"))
        .arg("--out")
        .arg(&out)
        .assert()
        .success();
    let first = std::fs::read_to_string(&out).unwrap();
    // A second import of the same input must be byte-identical (reproducible).
    let out2 = dir.path().join("corpus2.json");
    mcptest()
        .args(["ecosystem", "import", "--mcpcorpus"])
        .arg(sample("mcpcorpus-sample.json"))
        .arg("--out")
        .arg(&out2)
        .assert()
        .success();
    assert_eq!(first, std::fs::read_to_string(&out2).unwrap());
    assert!(first.contains("\"content_sha256\""));
}

#[test]
fn at_least_twenty_projects_select_into_a_fixture_pack() {
    let dir = tempfile::tempdir().unwrap();
    let corpus = dir.path().join("corpus.json");
    mcptest()
        .args(["ecosystem", "import", "--mcpcorpus"])
        .arg(sample("mcpcorpus-sample.json"))
        .arg("--out")
        .arg(&corpus)
        .assert()
        .success();

    let pack = dir.path().join("pack.json");
    mcptest()
        .args(["ecosystem", "select"])
        .arg(&corpus)
        .args(["--fixture-ready", "--limit", "20", "--out"])
        .arg(&pack)
        .assert()
        .success();

    let value: serde_json::Value =
        serde_json::from_str(&std::fs::read_to_string(&pack).unwrap()).unwrap();
    let entries = value["entries"].as_array().unwrap();
    assert_eq!(entries.len(), 20, "limit caps the pack at 20");
    assert!(
        value["matched"].as_u64().unwrap() >= 20,
        "at least 20 matched"
    );
}

#[test]
fn select_filters_by_transport() {
    let dir = tempfile::tempdir().unwrap();
    let corpus = dir.path().join("corpus.json");
    mcptest()
        .args(["ecosystem", "import", "--mcpcorpus"])
        .arg(sample("mcpcorpus-sample.json"))
        .arg("--out")
        .arg(&corpus)
        .assert()
        .success();

    mcptest()
        .args(["ecosystem", "select"])
        .arg(&corpus)
        .args(["--transport", "http"])
        .assert()
        .success()
        .stdout(predicate::str::contains("\"transport\": \"http\""));
}

#[test]
fn import_with_no_sources_is_a_usage_error() {
    mcptest().args(["ecosystem", "import"]).assert().code(2);
}
