"""Tests for compliance test runner."""

from __future__ import annotations

from ai4gh.compliance.runner import (
    ComplianceSuite,
    SuiteResult,
    TestResult,
    TestStatus,
    get_suite,
    list_suites,
    register_suite,
)


class TestTestStatus:
    def test_values(self) -> None:
        assert TestStatus.PASS == "pass"
        assert TestStatus.FAIL == "fail"
        assert TestStatus.SKIP == "skip"
        assert TestStatus.ERROR == "error"


class TestTestResult:
    def test_defaults(self) -> None:
        r = TestResult(name="test_foo", status=TestStatus.PASS)
        assert r.name == "test_foo"
        assert r.status == TestStatus.PASS
        assert r.message == ""
        assert r.duration_ms == 0.0

    def test_with_message(self) -> None:
        r = TestResult(
            name="test_bar",
            status=TestStatus.FAIL,
            message="Expected 200",
            endpoint="/api/v1",
        )
        assert r.message == "Expected 200"
        assert r.endpoint == "/api/v1"


class TestSuiteResult:
    def test_empty(self) -> None:
        sr = SuiteResult(spec="test", base_url="http://example.com")
        assert sr.total == 0
        assert sr.passed == 0
        assert sr.failed == 0
        assert sr.skipped == 0
        assert sr.errors == 0
        assert sr.success_rate == 0.0

    def test_with_results(self) -> None:
        sr = SuiteResult(
            spec="test",
            base_url="http://example.com",
            results=[
                TestResult(name="t1", status=TestStatus.PASS),
                TestResult(name="t2", status=TestStatus.PASS),
                TestResult(name="t3", status=TestStatus.FAIL),
                TestResult(name="t4", status=TestStatus.SKIP),
                TestResult(name="t5", status=TestStatus.ERROR),
            ],
        )
        assert sr.total == 5
        assert sr.passed == 2
        assert sr.failed == 1
        assert sr.skipped == 1
        assert sr.errors == 1
        assert sr.success_rate == 40.0


class TestComplianceSuite:
    async def test_run_collects_methods(self) -> None:
        class MySuite(ComplianceSuite):
            spec_name = "test"

            def test_alpha(self) -> TestResult:
                return TestResult(name="test_alpha", status=TestStatus.PASS, spec="test")

            def test_beta(self) -> TestResult:
                return TestResult(name="test_beta", status=TestStatus.FAIL, spec="test")

        suite = MySuite(base_url="http://localhost")
        result = await suite.run()
        assert result.spec == "test"
        assert result.total == 2
        assert result.passed == 1
        assert result.failed == 1

    async def test_run_handles_exceptions(self) -> None:
        class BadSuite(ComplianceSuite):
            spec_name = "bad"

            def test_broken(self) -> TestResult:
                raise ValueError("boom")

        suite = BadSuite(base_url="http://localhost")
        result = await suite.run()
        assert result.total == 1
        assert result.errors == 1
        assert "boom" in result.results[0].message

    async def test_run_handles_none_return(self) -> None:
        class NullSuite(ComplianceSuite):
            spec_name = "null"

            def test_implicit_pass(self) -> None:
                pass

        suite = NullSuite(base_url="http://localhost")
        result = await suite.run()
        assert result.total == 1
        assert result.passed == 1

    async def test_run_async_methods(self) -> None:
        class AsyncSuite(ComplianceSuite):
            spec_name = "async"

            async def test_async_one(self) -> TestResult:
                return TestResult(name="test_async_one", status=TestStatus.PASS, spec="async")

        suite = AsyncSuite(base_url="http://localhost")
        result = await suite.run()
        assert result.total == 1
        assert result.passed == 1


class TestRegistry:
    def test_register_and_get(self) -> None:
        @register_suite("test_spec_xyz")
        class XYZSuite(ComplianceSuite):
            spec_name = "test_spec_xyz"

        assert get_suite("test_spec_xyz") is XYZSuite

    def test_get_nonexistent(self) -> None:
        assert get_suite("nonexistent_spec_abc") is None

    def test_list_suites(self) -> None:
        # Import suites to trigger registration
        import ai4gh.compliance.suites  # noqa: F401

        specs = list_suites()
        assert "beacon" in specs
        assert "drs" in specs
        assert "wes" in specs
        assert "tes" in specs
        assert "trs" in specs
        assert "htsget" in specs
        assert "refget" in specs
