"""
Smart Router Tests - Phase 13.3
===============================
測試意圖分類、複雜度評分、AI 路由
"""

from src.services.ai_router import (
    AIRouter,
    get_ai_router,
)
from src.services.complexity_scorer import (
    ComplexityScorer,
    get_complexity_scorer,
)
from src.services.intent_classifier import (
    IntentClassifier,
    IntentType,
    get_intent_classifier,
)


class TestIntentClassifier:
    """測試意圖分類器"""

    def test_alert_keywords(self):
        """測試告警關鍵字匹配"""
        classifier = IntentClassifier()

        # 中文告警
        assert classifier.classify_sync("高負載警報") == IntentType.ALERT_TRIAGE
        assert classifier.classify_sync("CPU 異常告警") == IntentType.ALERT_TRIAGE
        assert classifier.classify_sync("OOM error detected") == IntentType.ALERT_TRIAGE

    def test_deployment_keywords(self):
        """測試部署關鍵字匹配"""
        classifier = IntentClassifier()

        assert classifier.classify_sync("部署新版本") == IntentType.DEPLOYMENT
        assert classifier.classify_sync("kubectl apply -f manifest.yaml") == IntentType.DEPLOYMENT
        assert classifier.classify_sync("rollout deployment api") == IntentType.DEPLOYMENT

    def test_query_keywords(self):
        """測試查詢關鍵字匹配"""
        classifier = IntentClassifier()

        assert classifier.classify_sync("查詢 Pod 狀態") == IntentType.QUERY
        assert classifier.classify_sync("kubectl get pods") == IntentType.QUERY
        assert classifier.classify_sync("現在有多少 replicas") == IntentType.QUERY

    def test_maintenance_keywords(self):
        """測試維運關鍵字匹配"""
        classifier = IntentClassifier()

        assert classifier.classify_sync("重啟服務") == IntentType.MAINTENANCE
        assert classifier.classify_sync("scale deployment to 5") == IntentType.MAINTENANCE
        assert classifier.classify_sync("回滾到上一版") == IntentType.MAINTENANCE

    def test_code_review_keywords(self):
        """測試程式碼審查關鍵字匹配"""
        classifier = IntentClassifier()

        assert classifier.classify_sync("review this PR") == IntentType.CODE_REVIEW
        assert classifier.classify_sync("審查這個 commit") == IntentType.CODE_REVIEW

    def test_unknown_intent(self):
        """測試未知意圖"""
        classifier = IntentClassifier()

        assert classifier.classify_sync("hello world") == IntentType.UNKNOWN
        assert classifier.classify_sync("今天天氣如何") == IntentType.UNKNOWN


class TestComplexityScorer:
    """測試複雜度評分器"""

    def test_simple_context(self):
        """測試簡單上下文"""
        scorer = ComplexityScorer()

        result = scorer.score({})
        assert result.score == 1
        assert result.recommended_model == "llama3.2:3b"

    def test_multi_service_context(self):
        """測試多服務上下文"""
        scorer = ComplexityScorer()

        result = scorer.score({
            "affected_services": ["api", "worker", "redis"],
        })
        assert result.score >= 2
        assert "service_count" in result.features

    def test_code_analysis_context(self):
        """測試需要程式碼分析"""
        scorer = ComplexityScorer()

        result = scorer.score({
            "requires_code_analysis": True,
        })
        assert result.score >= 2
        assert result.features.get("code_analysis") == 1

    def test_critical_severity(self):
        """測試 CRITICAL 嚴重程度"""
        scorer = ComplexityScorer()

        result = scorer.score({
            "severity": "CRITICAL",
        })
        assert result.score >= 2
        assert result.features.get("severity") == 4

    def test_complex_context(self):
        """測試複雜上下文"""
        scorer = ComplexityScorer()

        result = scorer.score({
            "affected_services": ["api", "worker", "redis", "postgres"],
            "metrics": ["cpu", "memory", "latency", "error_rate", "rps"],
            "cross_system": True,
            "severity": "CRITICAL",
        })
        assert result.score >= 4
        # 複雜情況應該用雲端模型
        assert result.recommended_model in ["gemini", "claude"]


class TestAIRouter:
    """測試 AI 路由器"""

    def test_query_routes_to_fast_model(self):
        """測試查詢路由到快速模型"""
        router = AIRouter()

        decision = router.route_sync("查詢 Pod 狀態", {})
        assert decision.model == "llama3.2:3b"
        assert decision.intent == IntentType.QUERY

    def test_code_review_routes_to_strong_model(self):
        """測試程式碼審查路由到強模型"""
        router = AIRouter()

        decision = router.route_sync("review this PR", {})
        assert decision.model == "qwen2.5:7b-instruct"
        assert decision.intent == IntentType.CODE_REVIEW

    def test_complex_alert_routes_to_cloud(self):
        """測試複雜告警路由到雲端"""
        router = AIRouter()

        decision = router.route_sync("高負載告警", {
            "affected_services": ["api", "worker", "redis", "postgres"],
            "metrics": ["cpu", "memory", "latency", "error_rate"],
            "cross_system": True,
            "severity": "CRITICAL",
        })
        assert decision.intent == IntentType.ALERT_TRIAGE
        assert decision.complexity.score >= 4
        # 高複雜度告警應該用雲端
        assert decision.model in ["gemini", "claude", "qwen2.5:7b-instruct"]

    def test_fallback_list(self):
        """測試 Fallback 列表"""
        router = AIRouter()

        decision = router.route_sync("查詢 Pod 狀態", {})
        # Fallback 不應包含已選模型
        assert decision.model not in decision.fallback_models
        # 應該有備援
        assert len(decision.fallback_models) >= 2


class TestSingletons:
    """測試單例"""

    def test_intent_classifier_singleton(self):
        """測試 IntentClassifier 單例"""
        c1 = get_intent_classifier()
        c2 = get_intent_classifier()
        assert c1 is c2

    def test_complexity_scorer_singleton(self):
        """測試 ComplexityScorer 單例"""
        s1 = get_complexity_scorer()
        s2 = get_complexity_scorer()
        assert s1 is s2

    def test_ai_router_singleton(self):
        """測試 AIRouter 單例"""
        r1 = get_ai_router()
        r2 = get_ai_router()
        assert r1 is r2
