"""Direct unit tests for _validator_render_diff covering metric-delta and
unchanged-with-primary branches."""
from __future__ import annotations

import supertool


def test_render_diff_unchanged_with_metric_delta() -> None:
    """Same count + ok, but a metric changed → emit metric delta row."""
    before = {"tool": "phpunit", "count": 0, "ok": True, "metrics": {"tests_total": 7}}
    after = {"tool": "phpunit", "count": 0, "ok": True, "metrics": {"tests_total": 10}}
    rows = supertool._validator_render_diff(before, after)
    joined = "".join(rows)
    assert "tests_total" in joined
    assert "7" in joined and "10" in joined


def test_render_diff_unchanged_falls_through_to_primary_metric() -> None:
    """No metric delta but absolute metric exists → 'unchanged' row with primary."""
    before = {"tool": "phpunit", "count": 0, "ok": True, "metrics": {"tests_total": 7}}
    after = {"tool": "phpunit", "count": 0, "ok": True, "metrics": {"tests_total": 7}}
    rows = supertool._validator_render_diff(before, after)
    joined = "".join(rows)
    assert "unchanged" in joined
    assert "tests_total" in joined


def test_render_diff_unchanged_no_metrics() -> None:
    """No metrics, same ok → simple unchanged row."""
    before = {"tool": "phpstan", "count": 0, "ok": True}
    after = {"tool": "phpstan", "count": 0, "ok": True}
    rows = supertool._validator_render_diff(before, after)
    joined = "".join(rows)
    assert "unchanged" in joined


def test_render_diff_metric_with_non_numeric_skipped() -> None:
    """Non-numeric metric values are ignored (not formatted)."""
    before = {"tool": "x", "count": 0, "ok": True, "metrics": {"label": "alpha", "count_n": 1}}
    after = {"tool": "x", "count": 0, "ok": True, "metrics": {"label": "beta", "count_n": 5}}
    rows = supertool._validator_render_diff(before, after)
    joined = "".join(rows)
    # Only numeric metric appears in the diff.
    assert "count_n" in joined and "5" in joined
    assert "label" not in joined


def test_render_diff_metric_bv_non_numeric_coerced_to_zero() -> None:
    """When before-value is non-numeric, it's treated as 0."""
    before = {"tool": "x", "count": 0, "ok": True, "metrics": {"k": "string"}}
    after = {"tool": "x", "count": 0, "ok": True, "metrics": {"k": 5}}
    rows = supertool._validator_render_diff(before, after)
    joined = "".join(rows)
    assert "k" in joined and "5" in joined


def test_render_diff_unchanged_timeout_marker() -> None:
    """Issue #228 — timeout-induced 'err' should render '(timeout)', not '(unchanged)'."""
    before = {"tool": "lsp-diag", "count": 1, "ok": False,
              "errors": [{"code": "orchestrator", "msg": "timeout after 3s"}],
              "timeout": True, "elapsed_s": 3.0}
    after = {"tool": "lsp-diag", "count": 1, "ok": False,
             "errors": [{"code": "orchestrator", "msg": "timeout after 3s"}],
             "timeout": True, "elapsed_s": 3.0}
    rows = supertool._validator_render_diff(before, after)
    joined = "".join(rows)
    assert "(timeout)" in joined
    assert "(unchanged)" not in joined


def test_render_diff_unchanged_real_err_labelled_pre_existing() -> None:
    """Issue #307 — a persisting error is labelled pre-existing, not '(unchanged)',
    and the error message is surfaced inline so the count is actionable."""
    before = {"tool": "jsonlint", "count": 1, "ok": False,
              "errors": [{"line": 4, "code": "E001", "msg": "trailing comma"}]}
    after = {"tool": "jsonlint", "count": 1, "ok": False,
             "errors": [{"line": 4, "code": "E001", "msg": "trailing comma"}]}
    rows = supertool._validator_render_diff(before, after)
    joined = "".join(rows)
    assert "pre-existing" in joined
    assert "not from this edit" in joined
    assert "(unchanged)" not in joined
    assert "(timeout)" not in joined
    # Error detail surfaced inline.
    assert "trailing comma" in joined
    assert "L4" in joined


def test_render_diff_pre_existing_caps_errors_at_five() -> None:
    """More than 5 persisting errors are capped with a '+N more' line."""
    errors = [{"line": i, "code": "E", "msg": f"err {i}"} for i in range(7)]
    before = {"tool": "phpstan", "count": 7, "ok": False, "errors": errors}
    after = {"tool": "phpstan", "count": 7, "ok": False, "errors": errors}
    rows = supertool._validator_render_diff(before, after)
    joined = "".join(rows)
    assert "pre-existing" in joined
    assert "+2 more" in joined
