# -*- coding: utf-8 -*-
"""
test_routes_troubleshoot.py — 排查相关路由测试

覆盖 routes/troubleshoot.py：troubleshoot / search_cases / analyze
/ analyze_stream / health_check / get_projects / get_categories
"""

from tests.conftest import MOCK_AI_RESPONSE


class TestTroubleshoot:
    """排查接口 POST /api/troubleshoot"""

    def test_empty_query(self, auth_client):
        """空 query 返回 400 + INVALID_PARAM"""
        r = auth_client.post("/api/troubleshoot", json={})
        assert r.status_code == 400
        assert r.get_json()["error"]["code"] == 1001

    def test_success(self, auth_client):
        """正常请求返回 200 + 响应内容（AI 已 mock）"""
        r = auth_client.post("/api/troubleshoot", json={
            "query": "mqtt 连接失败", "project_name": "测试"
        })
        assert r.status_code == 200
        data = r.get_json()
        assert data["success"] is True
        assert "response" in data
        assert "matched_cases" in data


class TestSearch:
    """搜索接口 POST /api/search"""

    def test_empty_query(self, auth_client):
        r = auth_client.post("/api/search", json={})
        assert r.status_code == 400
        assert r.get_json()["error"]["code"] == 1001

    def test_success(self, auth_client):
        r = auth_client.post("/api/search", json={"query": "mqtt"})
        assert r.status_code == 200
        data = r.get_json()
        assert data["success"] is True
        assert "matched_cases" in data
        assert "search_time" in data


class TestAnalyze:
    """分析接口 POST /api/analyze"""

    def test_empty_query(self, auth_client):
        r = auth_client.post("/api/analyze", json={})
        assert r.status_code == 400
        assert r.get_json()["error"]["code"] == 1001

    def test_success(self, auth_client):
        r = auth_client.post("/api/analyze", json={"query": "mqtt", "matched_cases": []})
        assert r.status_code == 200
        data = r.get_json()
        assert data["success"] is True
        assert "response" in data


class TestAnalyzeStream:
    """流式接口 GET /api/analyze/stream"""

    def test_empty_query_returns_error_event(self, auth_client):
        """空 query 返回 SSE 错误事件（HTTP 200，事件 type=error）"""
        r = auth_client.get("/api/analyze/stream?query=")
        assert r.status_code == 200
        assert r.mimetype == "text/event-stream"
        assert b'"type": "error"' in r.data

    def test_success_stream(self, auth_client):
        """正常流式请求返回 SSE 含 start/done 事件"""
        r = auth_client.get("/api/analyze/stream?query=mqtt")
        assert r.status_code == 200
        assert r.mimetype == "text/event-stream"
        assert b'"type": "start"' in r.data
        assert b'"type": "done"' in r.data

    def test_cached_stream(self, auth_client):
        """连续两次请求：第二次返回有效 SSE 流（缓存命中或重新生成都接受）"""
        auth_client.get("/api/analyze/stream?query=mqtt&project_name=cache_test")
        r2 = auth_client.get("/api/analyze/stream?query=mqtt&project_name=cache_test")
        assert r2.status_code == 200
        assert r2.mimetype == "text/event-stream"
        # 第二次必定包含 done 事件（无论缓存命中还是重新生成）
        assert b'"type": "done"' in r2.data


class TestHealth:
    """健康检查 GET /api/health"""

    def test_success(self, client):
        r = client.get("/api/health")
        assert r.status_code == 200
        data = r.get_json()
        assert data["status"] == "ok"
        assert data["knowledge_base"]["total_records"] == 357
        assert data["components"]["search_engine"] == "ok"


class TestProjectsAndCategories:
    """项目与分类接口"""

    def test_projects_unauthenticated(self, client):
        """未登录用户获取项目列表返回空（防止信息泄露）"""
        r = client.get("/api/projects")
        assert r.status_code == 200
        data = r.get_json()
        assert data["success"] is True
        assert data["projects"] == []

    def test_projects_normal_user(self, auth_client):
        """普通用户获取项目列表返回空（防止信息泄露）"""
        r = auth_client.get("/api/projects")
        assert r.status_code == 200
        data = r.get_json()
        assert data["success"] is True
        assert data["projects"] == []

    def test_projects_admin(self, admin_client):
        """管理员获取项目列表返回完整 120 项"""
        r = admin_client.get("/api/projects")
        assert r.status_code == 200
        data = r.get_json()
        assert data["success"] is True
        assert len(data["projects"]) == 120

    def test_categories(self, client):
        r = client.get("/api/categories")
        assert r.status_code == 200
        data = r.get_json()
        assert data["success"] is True
        assert len(data["categories"]) == 20
