"""Unit tests for github.scaffold — v2 bootstrap helpers (#81).

Covers the new mutation + state-read helpers added for scaffold_project
v2: `enable_discussions` and `get_repo_discussions_state`. The existing
v1 helpers (`get_organization_id`, `create_repository`, `create_label`)
are tested alongside resolvers in `test_github_resolvers.py`.
"""
from __future__ import annotations

import json
from unittest.mock import MagicMock, patch

import pytest

from active_claude_github_mcp.github.core import GitHubError
from active_claude_github_mcp.github.scaffold import (
    enable_discussions,
    get_repo_discussions_state,
)


TOKEN = "ghp_test_token"


def _mock_response(data: dict, status_code: int = 200):
    mock = MagicMock()
    mock.status_code = status_code
    mock.json.return_value = data
    mock.text = json.dumps(data)
    return mock


class TestGetRepoDiscussionsState:
    def test_empty_repo_id_raises(self):
        with pytest.raises(ValueError, match="repo_id"):
            get_repo_discussions_state(TOKEN, "")

    def test_repo_not_found_raises(self):
        response_data = {"data": {"node": None}}
        with patch("httpx.post", return_value=_mock_response(response_data)):
            with pytest.raises(GitHubError, match="not found"):
                get_repo_discussions_state(TOKEN, "R_missing")

    def test_returns_enablement_and_categories(self):
        response_data = {
            "data": {
                "node": {
                    "hasDiscussionsEnabled": True,
                    "discussionCategories": {
                        "nodes": [
                            {"id": "DIC_1", "name": "Project", "isAnswerable": False},
                            {"id": "DIC_2", "name": "Architecture", "isAnswerable": True},
                            {"id": "DIC_3", "name": "UX / UI", "isAnswerable": True},
                        ]
                    },
                }
            }
        }
        with patch("httpx.post", return_value=_mock_response(response_data)):
            state = get_repo_discussions_state(TOKEN, "R_dev")
        assert state["enabled"] is True
        assert set(state["categories"].keys()) == {"Project", "Architecture", "UX / UI"}
        assert state["categories"]["Architecture"]["isAnswerable"] is True
        assert state["categories"]["Project"]["id"] == "DIC_1"

    def test_not_yet_enabled_returns_false(self):
        response_data = {
            "data": {
                "node": {
                    "hasDiscussionsEnabled": False,
                    "discussionCategories": {"nodes": []},
                }
            }
        }
        with patch("httpx.post", return_value=_mock_response(response_data)):
            state = get_repo_discussions_state(TOKEN, "R_dev")
        assert state["enabled"] is False
        assert state["categories"] == {}

    def test_nameless_category_skipped(self):
        """Defensive: if GitHub ever returns a node without a name, skip it
        rather than blowing up."""
        response_data = {
            "data": {
                "node": {
                    "hasDiscussionsEnabled": True,
                    "discussionCategories": {
                        "nodes": [
                            {"id": "DIC_ok", "name": "Project", "isAnswerable": False},
                            {"id": "DIC_nameless", "name": None, "isAnswerable": False},
                        ]
                    },
                }
            }
        }
        with patch("httpx.post", return_value=_mock_response(response_data)):
            state = get_repo_discussions_state(TOKEN, "R_dev")
        assert list(state["categories"].keys()) == ["Project"]


class TestEnableDiscussions:
    def test_empty_repo_id_raises(self):
        with pytest.raises(ValueError, match="repo_id"):
            enable_discussions(TOKEN, "")

    def test_success_returns_true(self):
        response_data = {
            "data": {
                "updateRepository": {
                    "repository": {"id": "R_dev", "hasDiscussionsEnabled": True}
                }
            }
        }
        with patch("httpx.post", return_value=_mock_response(response_data)):
            assert enable_discussions(TOKEN, "R_dev") is True

    def test_github_error_propagates(self):
        response_data = {"errors": [{"message": "Insufficient scope"}]}
        with patch("httpx.post", return_value=_mock_response(response_data)):
            with pytest.raises(GitHubError, match="Insufficient scope"):
                enable_discussions(TOKEN, "R_dev")


if __name__ == "__main__":
    import sys
    sys.exit(pytest.main([__file__, "-v"]))
