"""搜索质量评测用例 — 30+ 查询覆盖 5 种类型

每个 case 定义:
- query: 搜索查询
- query_type: symbol_lookup / error_query / overview / cross_collection / cognition_specific
- expected_code: 期望在 corpus 结果中出现的文件路径子串列表
- expected_facts: 期望在 cognition 结果中出现的关键词列表（assertion 匹配）
- notes: 说明

评测指标:
- Hit@K: 前 K 条结果中是否命中至少一个 expected
- P@K: 前 K 条结果中命中 expected 的比例
- MRR: 第一个命中结果的排名倒数
"""

from __future__ import annotations

from dataclasses import dataclass, field


@dataclass
class EvalCase:
    query: str
    query_type: str  # symbol_lookup / error_query / overview / cognition_specific / cross_collection
    expected_code: list[str] = field(default_factory=list)    # 文件路径子串
    expected_facts: list[str] = field(default_factory=list)   # assertion 关键词
    notes: str = ""


# ── 1. Symbol Lookup: 精确符号 → 期望命中对应文件 ──

SYMBOL_LOOKUP_CASES = [
    EvalCase(
        query="search.py",
        query_type="symbol_lookup",
        expected_code=["search.py"],
        notes="直接文件名搜索",
    ),
    EvalCase(
        query="db_cog.py",
        query_type="symbol_lookup",
        expected_code=["db_cog.py"],
        notes="cognition 数据库文件",
    ),
    EvalCase(
        query="MaintenanceEngine",
        query_type="symbol_lookup",
        expected_code=["maintenance.py"],
        notes="类名搜索",
    ),
    EvalCase(
        query="unified_recall",
        query_type="symbol_lookup",
        expected_code=["unified_search.py"],
        notes="函数名搜索",
    ),
    EvalCase(
        query="preprocess_query",
        query_type="symbol_lookup",
        expected_code=["query.py"],
        notes="查询预处理函数",
    ),
    EvalCase(
        query="safe_db_write",
        query_type="symbol_lookup",
        expected_code=["resilience.py"],
        notes="容错原语函数",
    ),
]

# ── 2. Error Query: 错误/Bug 相关 → 期望命中 bug fix facts ──

ERROR_QUERY_CASES = [
    EvalCase(
        query="hooks.py TypeError",
        query_type="error_query",
        expected_facts=["TypeError", "hooks"],
        notes="Hook 中的类型错误",
    ),
    EvalCase(
        query="database connection error",
        query_type="error_query",
        expected_facts=["connection", "database"],
        expected_code=["db_cog.py"],
        notes="数据库连接错误",
    ),
    EvalCase(
        query="CircuitBreaker buffer",
        query_type="error_query",
        expected_facts=["CircuitBreaker", "buffer"],
        expected_code=["resilience.py"],
        notes="熔断器缓冲区",
    ),
    EvalCase(
        query="embedding dimension mismatch",
        query_type="error_query",
        expected_facts=["dimension", "embedding"],
        notes="向量维度不匹配",
    ),
    EvalCase(
        query="FTS5 index sync",
        query_type="error_query",
        expected_code=["db_cog.py", "db.py"],
        expected_facts=["FTS5"],
        notes="全文索引同步问题",
    ),
]

# ── 3. Overview: 架构/概览查询 → 期望命中 architecture facts ──

OVERVIEW_CASES = [
    EvalCase(
        query="Observer 降级链",
        query_type="overview",
        expected_facts=["Observer", "降级", "provider"],
        expected_code=["observer"],
        notes="Observer 5 provider 降级链",
    ),
    EvalCase(
        query="maintenance 维护步骤",
        query_type="overview",
        expected_facts=["maintenance", "步骤"],
        expected_code=["maintenance.py"],
        notes="维护引擎步骤",
    ),
    EvalCase(
        query="Hook 事件处理流程",
        query_type="overview",
        expected_facts=["Hook", "awaken", "orient", "observe", "reflect"],
        expected_code=["hooks.py"],
        notes="4 Hook 事件",
    ),
    EvalCase(
        query="搜索管线 RRF 融合",
        query_type="overview",
        expected_facts=["RRF", "BM25"],
        expected_code=["search.py"],
        notes="搜索管线融合策略",
    ),
    EvalCase(
        query="ONNX embedding backend",
        query_type="overview",
        expected_facts=["ONNX", "embedding"],
        expected_code=["embed_onnx.py", "embed.py"],
        notes="ONNX 默认后端",
    ),
    EvalCase(
        query="collection 推断降级链",
        query_type="overview",
        expected_facts=["collection", "推断"],
        expected_code=["collection.py"],
        notes="collection 自动检测",
    ),
]

# ── 4. Cross Collection: 期望 index1 集合优先 ──

CROSS_COLLECTION_CASES = [
    EvalCase(
        query="safe_db_write resilience",
        query_type="cross_collection",
        expected_code=["resilience.py"],
        expected_facts=["safe_db_write"],
        notes="容错函数 — index1 集合优先",
    ),
    EvalCase(
        query="tree-sitter symbol extraction",
        query_type="cross_collection",
        expected_code=["symbols.py"],
        expected_facts=["tree-sitter", "symbol"],
        notes="符号提取 — index1 集合",
    ),
    EvalCase(
        query="capture rules engine",
        query_type="cross_collection",
        expected_code=["capture.py"],
        expected_facts=["capture", "rule"],
        notes="规则引擎 — index1 集合",
    ),
]

# ── 5. Cognition Specific: 纯认知查询 → 期望命中 decision/tradeoff facts ──

COGNITION_CASES = [
    EvalCase(
        query="为什么用 ONNX 不用 Ollama 作为默认",
        query_type="cognition_specific",
        expected_facts=["ONNX", "默认"],
        notes="设计决策：ONNX 默认后端",
    ),
    EvalCase(
        query="worldview 表为什么不需要",
        query_type="cognition_specific",
        expected_facts=["worldview", "不需要"],
        notes="设计决策：worldview 表评估结论",
    ),
    EvalCase(
        query="evolve_neighbors TypeError 修复",
        query_type="cognition_specific",
        expected_facts=["evolve_neighbors", "TypeError"],
        notes="Bug fix 记录",
    ),
    EvalCase(
        query="Claude 不会主动调用工具",
        query_type="cognition_specific",
        expected_facts=["Claude", "主动", "调用"],
        notes="最坏假设设计原则",
    ),
    EvalCase(
        query="session_review 两阶段 prompt",
        query_type="cognition_specific",
        expected_facts=["session_review", "prompt"],
        notes="Session 评价回顾设计",
    ),
    EvalCase(
        query="Jaccard 中文停用词",
        query_type="cognition_specific",
        expected_facts=["Jaccard", "停用词"],
        notes="去重优化：中文停用词",
    ),
    EvalCase(
        query="expansion 质量控制 grounding",
        query_type="cognition_specific",
        expected_facts=["expansion", "grounding"],
        notes="查询扩展质量验证",
    ),
    EvalCase(
        query="prompt_analyzer L0 正则",
        query_type="cognition_specific",
        expected_facts=["prompt_analyzer", "L0"],
        notes="用户 prompt 分析模块",
    ),
]


# ── 全部用例 ──

ALL_CASES = (
    SYMBOL_LOOKUP_CASES
    + ERROR_QUERY_CASES
    + OVERVIEW_CASES
    + CROSS_COLLECTION_CASES
    + COGNITION_CASES
)
