"""Tests for milco history --last N and --failed filters."""

import json
from milco.cli import main


def _write_index(tmp_path, records):
    runs_dir = tmp_path / "runs"
    runs_dir.mkdir(exist_ok=True)
    lines = [json.dumps(r) for r in records]
    (runs_dir / "index.jsonl").write_text("\n".join(lines) + "\n", encoding="utf-8")


SAMPLE_RECORDS = [
    {
        "timestamp": "2026-01-01T00:00:00Z",
        "run_id": "r1",
        "command": "run",
        "mode": "dry_run",
        "decision": "PASS",
        "exit_code": 0,
        "git": {"commit": None, "branch": None},
        "paths": {"run_dir": "runs/r1", "manifest": "runs/r1/manifest.json"},
    },
    {
        "timestamp": "2026-01-02T00:00:00Z",
        "run_id": "r2",
        "command": "run",
        "mode": "apply",
        "decision": "REFUSED",
        "exit_code": 1,
        "git": {"commit": None, "branch": None},
        "paths": {"run_dir": "runs/r2", "manifest": "runs/r2/manifest.json"},
    },
    {
        "timestamp": "2026-01-03T00:00:00Z",
        "run_id": "r3",
        "command": "run",
        "mode": "dry_run",
        "decision": "PASS",
        "exit_code": 0,
        "git": {"commit": None, "branch": None},
        "paths": {"run_dir": "runs/r3", "manifest": "runs/r3/manifest.json"},
    },
    {
        "timestamp": "2026-01-04T00:00:00Z",
        "run_id": "r4",
        "command": "gate",
        "mode": "dry_run",
        "decision": "FAIL",
        "exit_code": 1,
        "git": {"commit": None, "branch": None},
        "paths": {"run_dir": "runs/r4", "manifest": "runs/r4/manifest.json"},
    },
]


def test_last_2_returns_2_rows(tmp_path, monkeypatch, capsys):
    _write_index(tmp_path, SAMPLE_RECORDS)
    monkeypatch.chdir(tmp_path)

    main(["history", "--last", "2"])
    out = capsys.readouterr().out
    lines = [line for line in out.strip().splitlines() if line.strip()]
    # header + separator + 2 data rows = 4 lines
    assert len(lines) == 4
    assert "r3" in lines[2]
    assert "r4" in lines[3]


def test_last_default_shows_all_when_fewer(tmp_path, monkeypatch, capsys):
    _write_index(tmp_path, SAMPLE_RECORDS)
    monkeypatch.chdir(tmp_path)

    main(["history"])
    out = capsys.readouterr().out
    lines = [line for line in out.strip().splitlines() if line.strip()]
    # header + separator + 4 data rows = 6
    assert len(lines) == 6


def test_failed_only(tmp_path, monkeypatch, capsys):
    _write_index(tmp_path, SAMPLE_RECORDS)
    monkeypatch.chdir(tmp_path)

    main(["history", "--failed"])
    out = capsys.readouterr().out
    lines = [line for line in out.strip().splitlines() if line.strip()]
    # header + separator + 2 failed rows = 4
    assert len(lines) == 4
    assert "r2" in out
    assert "r4" in out
    assert "r1" not in lines[2] and "r1" not in lines[3]


def test_failed_with_last(tmp_path, monkeypatch, capsys):
    _write_index(tmp_path, SAMPLE_RECORDS)
    monkeypatch.chdir(tmp_path)

    main(["history", "--failed", "--last", "1"])
    out = capsys.readouterr().out
    lines = [line for line in out.strip().splitlines() if line.strip()]
    # header + separator + 1 data row = 3
    assert len(lines) == 3
    assert "r4" in lines[2]


def test_json_output(tmp_path, monkeypatch, capsys):
    _write_index(tmp_path, SAMPLE_RECORDS)
    monkeypatch.chdir(tmp_path)

    main(["history", "--last", "2", "--json"])
    out = capsys.readouterr().out
    json_lines = [line for line in out.strip().splitlines() if line.strip()]
    assert len(json_lines) == 2
    r0 = json.loads(json_lines[0])
    r1 = json.loads(json_lines[1])
    assert r0["run_id"] == "r3"
    assert r1["run_id"] == "r4"


def test_no_matching_runs(tmp_path, monkeypatch, capsys):
    # All PASS records, then --failed should show "No matching runs."
    pass_records = [r for r in SAMPLE_RECORDS if r["exit_code"] == 0]
    _write_index(tmp_path, pass_records)
    monkeypatch.chdir(tmp_path)

    main(["history", "--failed"])
    out = capsys.readouterr().out
    assert "No matching runs" in out
