# Standard Library
from unittest.mock import Mock, patch

# Django
from django.test import RequestFactory

# Alliance Auth (Core)
from allianceauth.utils.testing import NoSocketsTestCase

from incursions.api import window as window_api


class FakeAPI:
    def __init__(self) -> None:
        self.routes: dict[str, object] = {}

    def post(self, path: str, **kwargs: object):
        def decorator(func):
            self.routes[path] = func
            return func
        return decorator


def _routes() -> dict[str, object]:
    api = FakeAPI()
    window_api.setup(api)
    return api.routes


def _user(**perms: bool) -> Mock:
    return Mock(has_perm=Mock(side_effect=lambda perm: perms.get(perm, False)))


class TestOpenWindow(NoSocketsTestCase):
    def setUp(self) -> None:
        self.factory = RequestFactory()
        self.routes = _routes()
        self.view = self.routes["/open_window"]

    def test_denies_without_permission(self) -> None:
        request = self.factory.post("/open_window")
        request.user = _user()

        response = self.view(request, window_api.OpenWindowRequest(character_id=1001, target_id=2002))

        self.assertEqual(response, (403, {"error": "Permission denied"}))

    @patch("incursions.api.window.open_window_information")
    def test_returns_result_from_provider(self, mock_open_window: Mock) -> None:
        mock_open_window.return_value = ({"status": "ok"}, Mock())
        request = self.factory.post("/open_window")
        request.user = _user(**{"incursions.waitlist_esi_show_info": True})

        response = self.view(request, window_api.OpenWindowRequest(character_id=1001, target_id=2002))

        self.assertEqual(response, {"status": "ok"})
        mock_open_window.assert_called_once_with(1001, 2002)
