"""Tests for axm audit report and @audit_track decorator."""

import time

from axm_audit.auditor import AuditMetrics, Auditor


class TestAuditTrackDecorator:
    """Tests for @audit_track decorator."""

    def test_audit_track_records_duration(self):
        """Decorator should record function execution time."""
        from axm_audit.decorators import audit_track

        auditor = Auditor()

        @audit_track(auditor=auditor)
        def slow_function():
            time.sleep(0.01)  # 10ms
            return "done"

        result = slow_function()

        assert result == "done"
        assert auditor.metrics.function_calls == 1
        assert auditor.metrics.function_duration_ns > 10_000_000  # > 10ms

    def test_audit_track_with_custom_name(self):
        """Decorator should use custom name if provided."""
        from axm_audit.decorators import audit_track

        auditor = Auditor()

        @audit_track(name="my_operation", auditor=auditor)
        def do_work():
            return 42

        do_work()

        assert "my_operation" in auditor.metrics.function_names

    def test_audit_track_preserves_exceptions(self):
        """Decorator should re-raise exceptions."""
        import pytest

        from axm_audit.decorators import audit_track

        auditor = Auditor()

        @audit_track(auditor=auditor)
        def failing_function():
            raise ValueError("test error")

        with pytest.raises(ValueError, match="test error"):
            failing_function()


class TestMetricsRegistry:
    """Tests for thread-safe MetricsRegistry."""

    def test_registry_get_creates_new(self):
        """Registry should create new metrics for unknown names."""
        from axm_audit.registry import MetricsRegistry

        registry = MetricsRegistry()
        metrics = registry.get("pipeline_1")

        assert isinstance(metrics, AuditMetrics)
        assert metrics.total_validations == 0

    def test_registry_get_returns_same(self):
        """Registry should return same metrics for same name."""
        from axm_audit.registry import MetricsRegistry

        registry = MetricsRegistry()
        m1 = registry.get("test")
        m2 = registry.get("test")

        assert m1 is m2

    def test_registry_thread_safe(self):
        """Registry should be thread-safe."""
        import threading

        from axm_audit.registry import MetricsRegistry

        registry = MetricsRegistry()
        results = []

        def worker(name):
            metrics = registry.get(name)
            results.append(metrics)

        threads = [threading.Thread(target=worker, args=(f"t{i}",)) for i in range(10)]
        for t in threads:
            t.start()
        for t in threads:
            t.join()

        assert len(results) == 10


class TestSLAThresholds:
    """Tests for SLA threshold checking."""

    def test_sla_passes_under_threshold(self):
        """SLA should pass when trust tax is under threshold."""
        from axm_audit.sla import SLAConfig, check_sla

        metrics = AuditMetrics(total_duration_ns=1_000_000)  # 1ms
        execution_ns = 1_000_000_000  # 1s
        config = SLAConfig(max_trust_tax_ratio=0.01)  # 1%

        result = check_sla(metrics, execution_ns, config)

        assert result.passed is True

    def test_sla_fails_over_threshold(self):
        """SLA should fail when trust tax exceeds threshold."""
        from axm_audit.sla import SLAConfig, check_sla

        metrics = AuditMetrics(total_duration_ns=100_000_000)  # 100ms
        execution_ns = 1_000_000_000  # 1s = 10% overhead
        config = SLAConfig(max_trust_tax_ratio=0.01)  # 1%

        result = check_sla(metrics, execution_ns, config)

        assert result.passed is False
        assert result.actual_ratio > 0.09
