"""Tests for compliance report generation."""

from __future__ import annotations

import json

from ai4gh.compliance.report import to_html, to_json, to_junit_xml
from ai4gh.compliance.runner import SuiteResult, TestResult, TestStatus


def _make_result() -> SuiteResult:
    return SuiteResult(
        spec="beacon",
        base_url="https://beacon.example.com",
        duration_ms=123.4,
        results=[
            TestResult(
                name="test_info",
                status=TestStatus.PASS,
                duration_ms=50.0,
                spec="beacon",
                endpoint="/info",
            ),
            TestResult(
                name="test_query",
                status=TestStatus.FAIL,
                message="Expected 200, got 500",
                duration_ms=30.0,
                spec="beacon",
                endpoint="/query",
            ),
            TestResult(
                name="test_optional",
                status=TestStatus.SKIP,
                message="Optional endpoint",
                duration_ms=1.0,
                spec="beacon",
            ),
            TestResult(
                name="test_broken",
                status=TestStatus.ERROR,
                message="Connection refused",
                duration_ms=10.0,
                spec="beacon",
            ),
        ],
    )


class TestJSONReport:
    def test_valid_json(self) -> None:
        result = _make_result()
        output = to_json(result)
        data = json.loads(output)
        assert data["spec"] == "beacon"
        assert data["base_url"] == "https://beacon.example.com"

    def test_summary(self) -> None:
        result = _make_result()
        data = json.loads(to_json(result))
        summary = data["summary"]
        assert summary["total"] == 4
        assert summary["passed"] == 1
        assert summary["failed"] == 1
        assert summary["skipped"] == 1
        assert summary["errors"] == 1
        assert summary["success_rate"] == 25.0

    def test_tests_array(self) -> None:
        result = _make_result()
        data = json.loads(to_json(result))
        assert len(data["tests"]) == 4
        assert data["tests"][0]["name"] == "test_info"
        assert data["tests"][0]["status"] == "pass"


class TestJUnitXMLReport:
    def test_valid_xml(self) -> None:
        result = _make_result()
        output = to_junit_xml(result)
        assert output.startswith('<?xml version="1.0"')
        assert "<testsuite" in output
        assert "</testsuite>" in output

    def test_contains_test_cases(self) -> None:
        result = _make_result()
        output = to_junit_xml(result)
        assert '<testcase name="test_info"' in output
        assert '<testcase name="test_query"' in output

    def test_failure_element(self) -> None:
        result = _make_result()
        output = to_junit_xml(result)
        assert "<failure" in output
        assert "Expected 200" in output

    def test_error_element(self) -> None:
        result = _make_result()
        output = to_junit_xml(result)
        assert "<error" in output
        assert "Connection refused" in output

    def test_skipped_element(self) -> None:
        result = _make_result()
        output = to_junit_xml(result)
        assert "<skipped" in output

    def test_attributes(self) -> None:
        result = _make_result()
        output = to_junit_xml(result)
        assert 'tests="4"' in output
        assert 'failures="1"' in output
        assert 'errors="1"' in output


class TestHTMLReport:
    def test_valid_html(self) -> None:
        result = _make_result()
        output = to_html(result)
        assert "<!DOCTYPE html>" in output
        assert "</html>" in output

    def test_contains_spec_name(self) -> None:
        result = _make_result()
        output = to_html(result)
        assert "beacon" in output

    def test_contains_test_names(self) -> None:
        result = _make_result()
        output = to_html(result)
        assert "test_info" in output
        assert "test_query" in output

    def test_contains_summary(self) -> None:
        result = _make_result()
        output = to_html(result)
        assert "25.0%" in output

    def test_escapes_html(self) -> None:
        result = SuiteResult(
            spec="test",
            base_url="http://example.com",
            results=[
                TestResult(
                    name="test_xss",
                    status=TestStatus.FAIL,
                    message="<script>alert(1)</script>",
                    spec="test",
                ),
            ],
        )
        output = to_html(result)
        assert "<script>" not in output
        assert "&lt;script&gt;" in output
