"""Smoke tests for the terminal banner + SVG report cards.

Cosmetic code, so the bar is: it renders without raising, produces well-formed
SVG, and includes the salient facts. This guards the scan/gate ``--card`` paths
from silently breaking.
"""
import xml.dom.minidom as minidom

from abom import bom, scan as scanner, viz
from pathlib import Path

FIX = Path(__file__).parent / "fixtures" / "sample-agent"


def _manifest():
    r = scanner.scan(FIX)
    return bom.build_composition(r["agent"], r["components"], r["controls"])


def _assert_valid_svg(s: str):
    assert s.lstrip().startswith("<svg")
    minidom.parseString(s)  # raises if malformed


def test_banner_renders_plain():
    out = viz.banner("0.1.0", color=False)
    assert "ABOM" in out
    assert "0.1.0" in out


def test_findings_table_plain_has_rows():
    m = _manifest()
    table = viz.findings_table(m["components"], color=False)
    assert "model" in table
    assert any(c["name"] in table for c in m["components"] if c.get("name"))


def test_findings_table_empty():
    assert isinstance(viz.findings_table([], color=False), str)


def test_scan_card_is_valid_svg():
    m = _manifest()
    svg = viz.scan_card(m)
    _assert_valid_svg(svg)
    assert m["agent"]["name"] in svg


def test_gate_card_allow_is_valid_svg():
    decision = {
        "verdict": "allow", "rule": None, "reason": "within envelope",
        "action": {"tool": "read_docs"},
        "tree_head": {"tree_size": 1, "root_hash": "ab" * 16},
    }
    svg = viz.gate_card(decision, "read_docs")
    _assert_valid_svg(svg)
    assert "read_docs" in svg


def test_gate_card_deny_is_valid_svg():
    decision = {
        "verdict": "deny", "rule": "tool_not_in_manifest", "reason": "undeclared tool",
        "action": {"tool": "wire_transfer"},
        "tree_head": {"tree_size": 2, "root_hash": "cd" * 16},
    }
    svg = viz.gate_card(decision, "wire_transfer")
    _assert_valid_svg(svg)
    assert "wire_transfer" in svg


def test_cards_escape_untrusted_text():
    """A component name with angle brackets must not break the SVG (XML-escaped)."""
    m = _manifest()
    m["components"].append({"type": "tool", "name": "<script>x</script>"})
    svg = viz.scan_card(m)
    _assert_valid_svg(svg)
    assert "<script>x</script>" not in svg  # escaped, not raw
