"""Tests for ZedIntegration."""

import json

import pytest

from specify_cli.integrations import get_integration

from .test_integration_base_skills import SkillsIntegrationTests


class TestZedIntegration(SkillsIntegrationTests):
    KEY = "zed"
    FOLDER = ".agents/"
    COMMANDS_SUBDIR = "skills"
    REGISTRAR_DIR = ".agents/skills"
    CONTEXT_FILE = "AGENTS.md"

    def test_options_include_skills_flag(self):
        """Not applicable to Zed — Zed is always skills-based with no --skills flag."""
        pytest.skip("Zed is always skills-based and does not expose a --skills option")

    def test_options_do_not_include_skills_flag(self):
        """Zed is always skills-based; no --skills option is exposed."""
        i = get_integration(self.KEY)
        assert i is not None
        opts = i.options()
        skills_opts = [o for o in opts if o.name == "--skills"]
        assert len(skills_opts) == 0, (
            "Zed is always skills-based and should not expose a --skills option"
        )

    def test_requires_cli_is_false(self):
        """Zed is IDE-based; requires_cli must remain False."""
        i = get_integration(self.KEY)
        assert i is not None
        assert i.config is not None
        assert i.config["requires_cli"] is False


class TestZedHookInvocations:
    """Zed hook messages should reference slash-invokable skills."""

    def test_hooks_render_skill_invocation(self, tmp_path):
        """Zed is always skills-based: renders /speckit-plan even with ai_skills=False."""
        from specify_cli.extensions import HookExecutor

        project = tmp_path / "zed-hooks"
        project.mkdir()
        init_options = project / ".specify" / "init-options.json"
        init_options.parent.mkdir(parents=True, exist_ok=True)
        init_options.write_text(json.dumps({"ai": "zed", "ai_skills": False}))

        hook_executor = HookExecutor(project)
        message = hook_executor.format_hook_message(
            "before_plan",
            [
                {
                    "extension": "test-ext",
                    "command": "speckit.plan",
                    "optional": False,
                }
            ],
        )

        assert "EXECUTE_COMMAND_INVOCATION: /speckit-plan" in message

    def test_init_persists_ai_skills_for_zed(self, tmp_path, monkeypatch):
        """specify init --integration zed must persist ai_skills: true,
        so HookExecutor renders slash-skill invocations without manual
        init-options manipulation."""
        from typer.testing import CliRunner

        from specify_cli import app
        from specify_cli.extensions import HookExecutor

        project = tmp_path / "zed-init-test"
        project.mkdir()
        monkeypatch.chdir(project)
        runner = CliRunner()
        result = runner.invoke(
            app,
            [
                "init",
                "--here",
                "--integration",
                "zed",
                "--script",
                "sh",
                "--ignore-agent-tools",
            ],
            catch_exceptions=False,
        )

        assert result.exit_code == 0, f"init failed: {result.output}"

        opts_path = project / ".specify" / "init-options.json"
        assert opts_path.exists()
        opts = json.loads(opts_path.read_text(encoding="utf-8"))
        assert opts.get("ai") == "zed"
        assert opts.get("ai_skills") is True, (
            f"init must persist ai_skills=true for Zed, got: {opts.get('ai_skills')}"
        )

        hook_executor = HookExecutor(project)
        message = hook_executor.format_hook_message(
            "before_plan",
            [
                {
                    "extension": "test-ext",
                    "command": "speckit.plan",
                    "optional": False,
                }
            ],
        )
        assert "Executing: `/speckit-plan`" in message, (
            "Hook rendering must produce /speckit-plan for Zed without hint injection"
        )
        assert "EXECUTE_COMMAND_INVOCATION: /speckit-plan" in message


class TestSlashSkillsSets:
    """Parameterized coverage for ALWAYS_SLASH_AGENTS / CONDITIONAL_SLASH_AGENTS."""

    @staticmethod
    def _render_invocation(project_path, ai: str, ai_skills: bool) -> str:
        """Return the rendered invocation for ``speckit.plan`` via HookExecutor."""
        from specify_cli.extensions import HookExecutor

        init_options = project_path / ".specify" / "init-options.json"
        init_options.parent.mkdir(parents=True, exist_ok=True)
        init_options.write_text(json.dumps({"ai": ai, "ai_skills": ai_skills}))
        hook_executor = HookExecutor(project_path)
        result = hook_executor.execute_hook(
            {"extension": "test-ext", "command": "speckit.plan", "optional": False}
        )
        return result.get("invocation", "")

    @pytest.mark.parametrize(
        ("ai", "ai_skills", "expected"),
        [
            # ALWAYS_SLASH_AGENTS — unconditional on ai_skills
            ("devin", True, "/speckit-plan"),
            ("devin", False, "/speckit-plan"),
            ("trae", True, "/speckit-plan"),
            ("trae", False, "/speckit-plan"),
            ("zed", True, "/speckit-plan"),
            ("zed", False, "/speckit-plan"),
            # CONDITIONAL_SLASH_AGENTS — only when ai_skills is enabled
            ("agy", True, "/speckit-plan"),
            ("agy", False, "/speckit.plan"),
            ("claude", True, "/speckit-plan"),
            ("claude", False, "/speckit.plan"),
            ("copilot", True, "/speckit-plan"),
            ("copilot", False, "/speckit.plan"),
            ("cursor-agent", True, "/speckit-plan"),
            ("cursor-agent", False, "/speckit.plan"),
        ],
    )
    def test_hook_invocation_format(self, tmp_path, ai, ai_skills, expected):
        result = self._render_invocation(tmp_path, ai, ai_skills)
        assert result == expected, (
            f"{ai} (ai_skills={ai_skills}): expected {expected!r}, got {result!r}"
        )
