import importlib.util
import json
import tempfile
import unittest
from pathlib import Path


def load_rebuilder():
    script_path = Path(__file__).resolve().parents[1] / "scripts" / "rebuild_indexes.py"
    spec = importlib.util.spec_from_file_location("rebuild_indexes", script_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module


class RebuildIndexesTests(unittest.TestCase):
    def write_json(self, root, relative_path, data):
        path = root / relative_path
        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")

    def write_library_without_indexes(self, root):
        self.write_json(root, "models/qpi.model.json", {
            "model_id": "qpi",
            "model_name": "QPI 三元定性模型",
            "model_type": "routing_model",
            "pipeline_position": "pre_analysis",
            "status": "draft",
            "source_articles": ["article_qpi_primary_001"],
            "source_evidence": ["excerpt_qpi_001"],
            "stability_profile": {"stability_level": "B"},
            "regression_status": "pending",
            "version": "0.1",
            "last_updated": "2026-06-16"
        })
        (root / "cards").mkdir(parents=True, exist_ok=True)
        (root / "cards" / "qpi.md").write_text("# QPI\n", encoding="utf-8")
        self.write_json(root, "tests/regression_cases.json", {
            "regression_cases": [
                {"case_id": "case_1", "model_id": "qpi"},
                {"case_id": "case_2", "model_id": "qpi"}
            ]
        })

    def test_write_rebuilds_model_and_card_indexes(self):
        rebuilder = load_rebuilder()
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            self.write_library_without_indexes(root)

            result = rebuilder.rebuild_indexes(root, write=True)

            self.assertFalse(result.drift_found)
            model_index = json.loads((root / "models" / "model_index.json").read_text(encoding="utf-8"))
            self.assertEqual(model_index["models"][0]["model_id"], "qpi")
            self.assertEqual(model_index["models"][0]["regression_case_count"], 2)
            self.assertEqual(model_index["models"][0]["status"], "draft")
            card_index = (root / "cards" / "card_index.md").read_text(encoding="utf-8")
            self.assertIn("| qpi | QPI 三元定性模型 | routing_model | pre_analysis |", card_index)
            self.assertTrue((root / "reports" / "index_rebuild_report.md").exists())

    def test_check_reports_drift_without_writing(self):
        rebuilder = load_rebuilder()
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            self.write_library_without_indexes(root)
            (root / "models" / "model_index.json").write_text("{}\n", encoding="utf-8")
            (root / "cards" / "card_index.md").write_text("# stale\n", encoding="utf-8")

            result = rebuilder.rebuild_indexes(root, write=False)

            self.assertTrue(result.drift_found)
            self.assertEqual((root / "models" / "model_index.json").read_text(encoding="utf-8"), "{}\n")


if __name__ == "__main__":
    unittest.main()
