"""Unit tests for test-case path parsing and fallback metric labeling behavior."""

from __future__ import annotations

import json
from pathlib import Path

from ci.scripts import publish_test_metrics


def test_collect_junit_cases_handles_missing_files_and_multiple_root_shapes(tmp_path: Path, monkeypatch):
    missing = tmp_path / "missing.xml"
    testsuites_path = tmp_path / "suite-cases.xml"
    testsuites_path.write_text(
        (
            "<testsuites>"
            '<testsuite tests="3">'
            '<testcase classname="alpha" name="ok_case" />'
            '<testcase classname="alpha" name="skip_case"><skipped /></testcase>'
            '<testcase classname="alpha"><failure /></testcase>'
            "</testsuite>"
            "</testsuites>"
        ),
        encoding="utf-8",
    )
    unknown_root_path = tmp_path / "unknown-root.xml"
    unknown_root_path.write_text("<root><testcase classname='x' name='ignored' /></root>", encoding="utf-8")

    monkeypatch.setattr(
        publish_test_metrics,
        "glob",
        lambda _pattern: [str(missing), str(testsuites_path), str(unknown_root_path)],
    )

    cases = publish_test_metrics._collect_junit_cases("ignored-glob")

    assert ("alpha.ok_case", "passed") in cases
    assert ("alpha.skip_case", "skipped") in cases
    assert not any(name.endswith("ignored") for name, _ in cases)


def test_build_payload_includes_explicit_test_case_series():
    payload = publish_test_metrics._build_payload(
        suite="titan-iac",
        status="ok",
        tests={"tests": 2, "failures": 1, "errors": 0, "skipped": 0},
        test_cases=[("alpha::case_one", "failed"), ("beta::case_two", "passed")],
        ok_count=3,
        failed_count=1,
        branch="main",
        build_number="5",
        jenkins_job="titan-iac",
        workspace_line_coverage_percent=95.0,
        source_lines_over_500=0,
        check_statuses={"tests": "failed"},
    )

    assert (
        'platform_quality_gate_test_case_result{suite="titan-iac",branch="main",build_number="5",jenkins_job="titan-iac",test="alpha::case_one",status="failed"} 1'
        in payload
    )
    assert (
        'platform_quality_gate_test_case_result{suite="titan-iac",branch="main",build_number="5",jenkins_job="titan-iac",test="beta::case_two",status="passed"} 1'
        in payload
    )


def test_main_uses_reported_coverage_and_loc_without_fallback(tmp_path: Path, monkeypatch, capsys):
    build_dir = tmp_path / "build"
    build_dir.mkdir()
    (build_dir / "junit.xml").write_text(
        '<testsuite tests="1" failures="0" errors="0" skipped="0" />',
        encoding="utf-8",
    )
    (build_dir / "quality-gate.rc").write_text("0\n", encoding="utf-8")
    (build_dir / "quality-gate-summary.json").write_text(
        json.dumps(
            {
                "workspace_line_coverage_percent": 99.5,
                "source_lines_over_500": 2,
                "results": [],
            }
        ),
        encoding="utf-8",
    )

    monkeypatch.setenv("JUNIT_GLOB", str(build_dir / "*.xml"))
    monkeypatch.setenv("QUALITY_GATE_EXIT_CODE_PATH", str(build_dir / "quality-gate.rc"))
    monkeypatch.setenv("QUALITY_GATE_SUMMARY_PATH", str(build_dir / "quality-gate-summary.json"))
    monkeypatch.setattr(publish_test_metrics, "_fetch_existing_counter", lambda *args, **kwargs: 0)
    monkeypatch.setattr(publish_test_metrics, "_post_text", lambda *args, **kwargs: None)
    monkeypatch.setattr(
        publish_test_metrics,
        "_infer_workspace_coverage_percent",
        lambda *args, **kwargs: (_ for _ in ()).throw(AssertionError("should not infer coverage")),
    )
    monkeypatch.setattr(
        publish_test_metrics,
        "_infer_source_lines_over_500",
        lambda *args, **kwargs: (_ for _ in ()).throw(AssertionError("should not infer loc")),
    )

    rc = publish_test_metrics.main()

    summary = json.loads(capsys.readouterr().out)
    assert rc == 0
    assert summary["workspace_line_coverage_percent"] == 99.5
    assert summary["source_lines_over_500"] == 2


def test_main_falls_back_to_inferred_coverage_and_loc(tmp_path: Path, monkeypatch, capsys):
    build_dir = tmp_path / "build"
    build_dir.mkdir()
    (build_dir / "junit.xml").write_text(
        '<testsuite tests="1" failures="0" errors="0" skipped="0" />',
        encoding="utf-8",
    )
    (build_dir / "quality-gate.rc").write_text("1\n", encoding="utf-8")
    (build_dir / "quality-gate-summary.json").write_text(
        json.dumps({"workspace_line_coverage_percent": 0.0, "source_lines_over_500": 0, "results": []}),
        encoding="utf-8",
    )

    posted = {}
    monkeypatch.setenv("JUNIT_GLOB", str(build_dir / "*.xml"))
    monkeypatch.setenv("QUALITY_GATE_EXIT_CODE_PATH", str(build_dir / "quality-gate.rc"))
    monkeypatch.setenv("QUALITY_GATE_SUMMARY_PATH", str(build_dir / "quality-gate-summary.json"))
    monkeypatch.setattr(publish_test_metrics, "_fetch_existing_counter", lambda *args, **kwargs: 0)
    monkeypatch.setattr(publish_test_metrics, "_post_text", lambda url, payload: posted.update({"url": url, "payload": payload}))
    monkeypatch.setattr(publish_test_metrics, "_infer_workspace_coverage_percent", lambda *args, **kwargs: 96.4)
    monkeypatch.setattr(publish_test_metrics, "_infer_source_lines_over_500", lambda *args, **kwargs: 7)

    rc = publish_test_metrics.main()

    summary = json.loads(capsys.readouterr().out)
    assert rc == 0
    assert summary["status"] == "failed"
    assert summary["workspace_line_coverage_percent"] == 96.4
    assert summary["source_lines_over_500"] == 7
    assert 'platform_quality_gate_workspace_line_coverage_percent{suite="titan_iac"} 96.400' in posted["payload"]
    assert 'platform_quality_gate_source_lines_over_500_total{suite="titan_iac"} 7' in posted["payload"]
