//! `mcptest matchers` prints the matcher catalog.
//!
//! Why: matcher names were only discoverable by reading the schema or the
//! docs, so agents kept guessing (and typoing) them. The catalog itself
//! lives in [`mcptest_core::matchers::catalog`]; drift against
//! `schemas/v1.json` is pinned by `tests/cli_matchers.rs`.

use anyhow::Result;
use mcptest_core::matchers::catalog::{CatalogEntry, EntryKind, CATALOG};
use serde_json::json;

/// Print the catalog, human-readable by default or as a JSON array with
/// `--json`. Always exits 0: listing what exists is never an error.
pub fn run_matchers(as_json: bool) -> Result<i32> {
    if as_json {
        let rows: Vec<serde_json::Value> = CATALOG
            .iter()
            .map(|e| {
                json!({
                    "name": e.name,
                    "description": e.description,
                    "example": e.example,
                })
            })
            .collect();
        println!("{}", serde_json::to_string_pretty(&rows)?);
        return Ok(0);
    }
    println!("Matchers (keys inside an assertion's `matcher:` object):\n");
    for entry in CATALOG.iter().filter(|e| e.kind == EntryKind::Matcher) {
        print_entry(entry);
    }
    println!("Expectation-level checks (keys on the long-form `expect:` block):\n");
    for entry in CATALOG.iter().filter(|e| e.kind == EntryKind::Expectation) {
        print_entry(entry);
    }
    Ok(0)
}

/// Render one catalog row: name, description, then the example indented so
/// it reads as a YAML block under the name.
fn print_entry(entry: &CatalogEntry) {
    println!("  {}", entry.name);
    println!("    {}", entry.description);
    for line in entry.example.lines() {
        println!("      {line}");
    }
    println!();
}
