"""prompt_analyzer.py 单元测试 — L0 用户 prompt 高价值 fact 提取"""

import json

from index1.cognitive.prompt_analyzer import extract_from_prompt


class TestExtractFromPrompt:
    def test_constraint_chinese(self):
        facts = extract_from_prompt(
            "禁止使用全局变量。所有状态必须通过参数传递",
            collection="test-proj",
            session_id="s1",
        )
        assert len(facts) >= 1
        assert any(f["category"] == "constraint" for f in facts)
        assert all(f["source"] == "prompt_l0" for f in facts)

    def test_constraint_english(self):
        facts = extract_from_prompt(
            "You must always use type hints. Never use bare except.",
            collection="test-proj",
            session_id="s1",
        )
        assert len(facts) >= 1
        assert any(f["category"] == "constraint" for f in facts)

    def test_preference(self):
        facts = extract_from_prompt(
            "优先使用 ONNX 而不是 Ollama 做 embedding",
            collection="test-proj",
            session_id="s1",
        )
        assert len(facts) >= 1
        assert any(f["category"] == "preference" for f in facts)

    def test_decision(self):
        facts = extract_from_prompt(
            "我们决定采用 SQLite 而不是 PostgreSQL",
            collection="test-proj",
            session_id="s1",
        )
        assert len(facts) >= 1
        assert any(f["category"] == "decision" for f in facts)

    def test_no_high_value_content(self):
        """纯代码操作描述 → 返回空列表"""
        facts = extract_from_prompt(
            "帮我修改 config.py 文件",
            collection="test-proj",
            session_id="s1",
        )
        # "config" 类别被跳过
        assert len(facts) == 0

    def test_empty_prompt(self):
        assert extract_from_prompt("", "test", "s1") == []

    def test_short_prompt(self):
        assert extract_from_prompt("ok", "test", "s1") == []

    def test_max_facts_limit(self):
        """每个 prompt 最多 3 条 fact"""
        facts = extract_from_prompt(
            "禁止使用全局变量。必须写类型注解。"
            "不允许裸 except。绝不跳过测试。"
            "一定要写文档。",
            collection="test-proj",
            session_id="s1",
        )
        assert len(facts) <= 3

    def test_fact_dict_format(self):
        """验证返回的 fact dict 格式正确"""
        facts = extract_from_prompt(
            "必须使用 safe_db_write 进行所有数据库写操作",
            collection="test-proj",
            session_id="s1",
        )
        assert len(facts) == 1
        f = facts[0]
        assert f["collection"] == "test-proj"
        assert f["session_id"] == "s1"
        assert f["source"] == "prompt_l0"
        assert f["status"] == "active"
        assert 0.7 <= f["confidence"] <= 0.95
        # scope_files 等字段是 JSON string
        json.loads(f["scope_files"])
        json.loads(f["scope_modules"])
        json.loads(f["scope_entities"])
        json.loads(f["context_json"])

    def test_architecture_extracted(self):
        facts = extract_from_prompt(
            "这个模块依赖 corpus 和 cognition 两个子系统的分层架构",
            collection="test-proj",
            session_id="s1",
        )
        assert len(facts) >= 1
        assert any(f["category"] == "architecture" for f in facts)

    def test_root_cause_extracted(self):
        facts = extract_from_prompt(
            "这个 bug 的根因是 asyncio event loop 冲突导致的死锁",
            collection="test-proj",
            session_id="s1",
        )
        assert len(facts) >= 1
        assert any(f["category"] == "root_cause" for f in facts)
