"""Tests for install_hooks version-check logic."""

from llm_router.install_hooks import _rules_version, check_and_update_rules


class TestRulesVersion:
    def test_no_header_returns_zero(self, tmp_path):
        f = tmp_path / "rules.md"
        f.write_text("# Some Rules\n\nContent here.\n")
        assert _rules_version(f) == 0

    def test_missing_file_returns_zero(self, tmp_path):
        assert _rules_version(tmp_path / "nonexistent.md") == 0

    def test_parses_version_header(self, tmp_path):
        f = tmp_path / "rules.md"
        f.write_text("<!-- llm-router-rules-version: 5 -->\n# Rules\n")
        assert _rules_version(f) == 5

    def test_version_with_extra_spaces(self, tmp_path):
        f = tmp_path / "rules.md"
        f.write_text("<!--  llm-router-rules-version:  3  -->\n# Rules\n")
        assert _rules_version(f) == 3

    def test_version_not_on_first_line_ignored(self, tmp_path):
        f = tmp_path / "rules.md"
        f.write_text("# Rules\n<!-- llm-router-rules-version: 7 -->\n")
        assert _rules_version(f) == 0

    def test_bundled_rules_have_version(self):
        """The bundled source rules file must have a version header."""
        from llm_router.install_hooks import _RULES_SRC
        bundled = _RULES_SRC / "llm-router.md"
        assert bundled.exists(), "Bundled rules file is missing"
        assert _rules_version(bundled) > 0, "Bundled rules must have a version header"


class TestCheckAndUpdateRules:
    def test_copies_when_installed_version_older(self, tmp_path, monkeypatch):
        src_dir = tmp_path / "src"
        dst_dir = tmp_path / "dst"
        src_dir.mkdir()
        dst_dir.mkdir()

        (src_dir / "llm-router.md").write_text(
            "<!-- llm-router-rules-version: 3 -->\n# New rules\n"
        )
        (dst_dir / "llm-router.md").write_text(
            "<!-- llm-router-rules-version: 1 -->\n# Old rules\n"
        )

        monkeypatch.setattr("llm_router.install_hooks._RULES_SRC", src_dir)
        monkeypatch.setattr("llm_router.install_hooks._RULES_DST", dst_dir)

        msg = check_and_update_rules()
        assert msg is not None
        assert "1 → 3" in msg or "v1" in msg
        assert (dst_dir / "llm-router.md").read_text().startswith(
            "<!-- llm-router-rules-version: 3 -->"
        )

    def test_no_update_when_versions_equal(self, tmp_path, monkeypatch):
        src_dir = tmp_path / "src"
        dst_dir = tmp_path / "dst"
        src_dir.mkdir()
        dst_dir.mkdir()

        content = "<!-- llm-router-rules-version: 2 -->\n# Rules\n"
        (src_dir / "llm-router.md").write_text(content)
        (dst_dir / "llm-router.md").write_text(content)

        monkeypatch.setattr("llm_router.install_hooks._RULES_SRC", src_dir)
        monkeypatch.setattr("llm_router.install_hooks._RULES_DST", dst_dir)

        assert check_and_update_rules() is None

    def test_no_update_when_installed_newer(self, tmp_path, monkeypatch):
        src_dir = tmp_path / "src"
        dst_dir = tmp_path / "dst"
        src_dir.mkdir()
        dst_dir.mkdir()

        (src_dir / "llm-router.md").write_text(
            "<!-- llm-router-rules-version: 1 -->\n# Old\n"
        )
        (dst_dir / "llm-router.md").write_text(
            "<!-- llm-router-rules-version: 5 -->\n# Newer\n"
        )

        monkeypatch.setattr("llm_router.install_hooks._RULES_SRC", src_dir)
        monkeypatch.setattr("llm_router.install_hooks._RULES_DST", dst_dir)

        assert check_and_update_rules() is None

    def test_copies_when_installed_has_no_version(self, tmp_path, monkeypatch):
        src_dir = tmp_path / "src"
        dst_dir = tmp_path / "dst"
        src_dir.mkdir()
        dst_dir.mkdir()

        (src_dir / "llm-router.md").write_text(
            "<!-- llm-router-rules-version: 2 -->\n# New\n"
        )
        (dst_dir / "llm-router.md").write_text("# Old rules without version\n")

        monkeypatch.setattr("llm_router.install_hooks._RULES_SRC", src_dir)
        monkeypatch.setattr("llm_router.install_hooks._RULES_DST", dst_dir)

        msg = check_and_update_rules()
        assert msg is not None

    def test_no_op_when_src_missing(self, tmp_path, monkeypatch):
        src_dir = tmp_path / "src"
        dst_dir = tmp_path / "dst"
        src_dir.mkdir()
        dst_dir.mkdir()

        monkeypatch.setattr("llm_router.install_hooks._RULES_SRC", src_dir)
        monkeypatch.setattr("llm_router.install_hooks._RULES_DST", dst_dir)

        assert check_and_update_rules() is None
