# -*- coding: utf-8 -*-
"""
P1-2 单元测试公共配置（conftest.py）

职责：
  1. 把 skill/code/web/ 加入 sys.path，让 tests/ 下测试可直接 import safety_filter 等模块
  2. autouse fixture：把 search_engine.SEARCH_INDEX_PATHS 指向仓库内 deploy/搜索索引.json 副本，
     避免 SearchEngine() 在本地开发环境抛 FileNotFoundError（生产环境靠 /opt/troubleshoot/搜索索引.json 加载）

参考：HANDOFF.md 坑 6 —— 永远以实际代码为准；本文件不复制大索引、不污染源码。
"""

import sys
from pathlib import Path

# ============================================================
# 路径定位
# ============================================================
# conftest.py 位于 skill/code/tests/conftest.py
TESTS_DIR = Path(__file__).resolve().parent          # .../skill/code/tests
WEB_DIR = TESTS_DIR.parent / "web"                   # .../skill/code/web
REPO_ROOT = TESTS_DIR.parents[2]                     # .../troubleshoot-ai-assistant（仓库根）
INDEX_FILE = REPO_ROOT / "deploy" / "搜索索引.json"   # 仓库内现成索引副本（357 条）

# 把 web/ 加入 sys.path（置顶，优先于其它路径）
if str(WEB_DIR) not in sys.path:
    sys.path.insert(0, str(WEB_DIR))

import pytest  # noqa: E402  (sys.path 已就位后才 import)


@pytest.fixture(autouse=True)
def _patch_search_index(monkeypatch):
    """
    autouse：每个测试前，把 search_engine 的索引查找路径替换为仓库内副本。

    作用对象：search_engine.SEARCH_INDEX_PATHS（模块级常量，find_search_index() 内部遍历它）。
    对不涉及 search_engine 的测试（safety_filter / cache_manager）无副作用。
    """
    import search_engine
    monkeypatch.setattr(search_engine, "SEARCH_INDEX_PATHS", [INDEX_FILE])


@pytest.fixture
def index_file():
    """返回仓库内索引副本路径，供测试断言可用性"""
    return INDEX_FILE


# ============================================================
# 路由层测试 fixture（P1 收尾三项）
# ============================================================

# AI 调用的 mock 响应（避免路由测试真实调用 AI API）
MOCK_AI_RESPONSE = "### 🔬 排查步骤（只读操作）\nStep 1: docker ps -a 查看容器\n"


@pytest.fixture
def app(tmp_path, monkeypatch):
    """Flask app（test client 用）。

    - TESTING=True
    - mock container.get_cache_manager 返回 tmp_path 隔离的 CacheManager（不碰真实 cache 目录）
    - mock ai_service 的 call_claude_api / call_claude_api_stream（不真实调用 AI）
    - mock submit 路由的 RECORDS_DIR + rebuild_search_index（不真写文件、不真跑子进程）
    """
    # 隔离缓存目录
    import container
    from cache_manager import CacheManager
    _cache = CacheManager(tmp_path / "cache", expire_hours=24)
    monkeypatch.setattr(container, "get_cache_manager", lambda: _cache)

    # mock AI 调用
    import services.ai_service as ai_service
    monkeypatch.setattr(ai_service, "call_claude_api", lambda prompt: MOCK_AI_RESPONSE)
    monkeypatch.setattr(ai_service, "call_claude_api_stream", lambda prompt, model=None: [MOCK_AI_RESPONSE])

    # 隔离 submit 的文件写入与索引重建
    import utils.paths
    monkeypatch.setattr(utils.paths, "RECORDS_DIR", tmp_path / "records")
    monkeypatch.setattr(utils.paths, "PROJECT_ROOT", tmp_path)
    import services.record_service as record_service
    monkeypatch.setattr(record_service, "rebuild_search_index", lambda: None)

    # conftest 顶部 _patch_search_index 已 autouse 注入索引路径，此处创建 app
    import server
    application = server.create_app()
    application.config["TESTING"] = True
    return application


@pytest.fixture
def client(app):
    """未登录的 test client"""
    return app.test_client()


@pytest.fixture
def auth_client(client):
    """已登录普通用户的 test client"""
    with client.session_transaction() as sess:
        sess["user"] = {"id": 1, "username": "testuser", "role": "user"}
    return client


@pytest.fixture
def admin_client(client):
    """已登录管理员的 test client"""
    with client.session_transaction() as sess:
        sess["user"] = {"id": 2, "username": "admin", "role": "admin"}
    return client
