"""Tests for bootstrap — auto-install hooks into .claude/settings.json."""

import json

from neo_cortex.bootstrap import BootstrapResult, ensure_hooks


def test_no_mcp_json(tmp_path):
    """Skip bootstrap if no .mcp.json at project root."""
    result = ensure_hooks(tmp_path)
    assert result.error == "no .mcp.json at project root"
    assert not result.session_start_installed
    assert not result.stop_installed


def test_fresh_install(tmp_path):
    """Install both hooks from scratch."""
    (tmp_path / ".mcp.json").write_text("{}")
    result = ensure_hooks(tmp_path)
    assert result.error is None
    assert result.created_dir
    assert result.created_file
    assert result.session_start_installed
    assert result.stop_installed
    assert not result.already_present
    data = json.loads((tmp_path / ".claude" / "settings.json").read_text())
    assert len(data["hooks"]["SessionStart"]) == 1
    assert "neo-cortex-timeline" in data["hooks"]["SessionStart"][0]["hooks"][0]["command"]
    assert len(data["hooks"]["Stop"]) == 1
    assert "neo-cortex-stop-hook" in data["hooks"]["Stop"][0]["hooks"][0]["command"]


def test_already_installed(tmp_path):
    """Skip if hooks already present."""
    (tmp_path / ".mcp.json").write_text("{}")
    (tmp_path / ".claude").mkdir()
    (tmp_path / ".claude" / "settings.json").write_text(json.dumps({
        "hooks": {
            "SessionStart": [{"matcher": "*", "hooks": [{"type": "command", "command": "uvx --from neo-cortex-mcp@latest neo-cortex-timeline --n 10", "timeout": 15}]}],
            "Stop": [{"matcher": "*", "hooks": [{"type": "command", "command": "uvx --from neo-cortex-mcp@latest neo-cortex-stop-hook", "timeout": 10}]}],
        }
    }))
    result = ensure_hooks(tmp_path)
    assert result.already_present
    assert not result.session_start_installed
    assert not result.stop_installed


def test_partial_install_missing_session_start(tmp_path):
    """Install only SessionStart when Stop already present."""
    (tmp_path / ".mcp.json").write_text("{}")
    (tmp_path / ".claude").mkdir()
    (tmp_path / ".claude" / "settings.json").write_text(json.dumps({
        "hooks": {
            "Stop": [{"matcher": "*", "hooks": [{"type": "command", "command": "neo-cortex-stop-hook", "timeout": 10}]}],
        }
    }))
    result = ensure_hooks(tmp_path)
    assert result.session_start_installed
    assert not result.stop_installed
    data = json.loads((tmp_path / ".claude" / "settings.json").read_text())
    assert len(data["hooks"]["SessionStart"]) == 1
    assert len(data["hooks"]["Stop"]) == 1


def test_preserves_existing_hooks_and_permissions(tmp_path):
    """Other hooks and permissions must survive."""
    (tmp_path / ".mcp.json").write_text("{}")
    (tmp_path / ".claude").mkdir()
    (tmp_path / ".claude" / "settings.json").write_text(json.dumps({
        "permissions": {"allow": ["Read"]},
        "hooks": {
            "SessionStart": [{"matcher": "*", "hooks": [{"type": "command", "command": "echo hello"}]}],
        }
    }))
    result = ensure_hooks(tmp_path)
    assert result.session_start_installed
    assert result.stop_installed
    data = json.loads((tmp_path / ".claude" / "settings.json").read_text())
    assert len(data["hooks"]["SessionStart"]) == 2
    assert data["hooks"]["SessionStart"][0]["hooks"][0]["command"] == "echo hello"
    assert "neo-cortex-timeline" in data["hooks"]["SessionStart"][1]["hooks"][0]["command"]
    assert data["permissions"] == {"allow": ["Read"]}


def test_corrupted_json(tmp_path):
    """Handle corrupted settings.json gracefully."""
    (tmp_path / ".mcp.json").write_text("{}")
    (tmp_path / ".claude").mkdir()
    (tmp_path / ".claude" / "settings.json").write_text("not json {{{")
    result = ensure_hooks(tmp_path)
    assert result.session_start_installed
    assert result.stop_installed
    data = json.loads((tmp_path / ".claude" / "settings.json").read_text())
    assert "hooks" in data


def test_idempotent(tmp_path):
    """Running twice produces same result."""
    (tmp_path / ".mcp.json").write_text("{}")
    r1 = ensure_hooks(tmp_path)
    assert r1.session_start_installed
    r2 = ensure_hooks(tmp_path)
    assert r2.already_present
    assert not r2.session_start_installed
    data = json.loads((tmp_path / ".claude" / "settings.json").read_text())
    assert len(data["hooks"]["SessionStart"]) == 1
    assert len(data["hooks"]["Stop"]) == 1
