from __future__ import annotations

import unittest

from govoplan_core.core.poll_participation import (
    CAPABILITY_POLL_PARTICIPATION_GATEWAY,
    PollParticipationGatewayProvider,
    PollParticipationPolicy,
    participation_token_fingerprint,
    poll_participation_gateway_provider,
)


class _CompleteGateway:
    def create_governed_invitation(self, *args, **kwargs):
        raise NotImplementedError

    def resolve_participation(self, *args, **kwargs):
        raise NotImplementedError

    def submit_governed_response(self, *args, **kwargs):
        raise NotImplementedError

    def resolve_authenticated_participation(self, *args, **kwargs):
        raise NotImplementedError

    def submit_authenticated_response(self, *args, **kwargs):
        raise NotImplementedError

    def add_option(self, *args, **kwargs):
        raise NotImplementedError

    def remove_option(self, *args, **kwargs):
        raise NotImplementedError

    def revoke_invitation(self, *args, **kwargs):
        raise NotImplementedError

    def update_invitation_expiry(self, *args, **kwargs):
        raise NotImplementedError


class _Registry:
    def __init__(self, capability: object | None) -> None:
        self.capability_value = capability

    def has_capability(self, name: str) -> bool:
        return (
            name == CAPABILITY_POLL_PARTICIPATION_GATEWAY
            and self.capability_value is not None
        )

    def capability(self, name: str) -> object:
        if not self.has_capability(name):
            raise KeyError(name)
        return self.capability_value


class PollParticipationContractTests(unittest.TestCase):
    def test_capability_name_and_policy_defaults_remain_stable(self) -> None:
        policy = PollParticipationPolicy()

        self.assertEqual("poll.participation_gateway", CAPABILITY_POLL_PARTICIPATION_GATEWAY)
        self.assertEqual(1, policy.version)
        self.assertTrue(policy.allow_maybe)

    def test_token_fingerprint_is_deterministic_and_non_reversible(self) -> None:
        fingerprint = participation_token_fingerprint("secret-token")

        self.assertEqual(fingerprint, participation_token_fingerprint("secret-token"))
        self.assertEqual(64, len(fingerprint))
        self.assertNotIn("secret-token", fingerprint)

    def test_registry_lookup_accepts_only_the_complete_structural_contract(self) -> None:
        provider = _CompleteGateway()

        self.assertIsInstance(provider, PollParticipationGatewayProvider)
        self.assertIs(provider, poll_participation_gateway_provider(_Registry(provider)))
        self.assertIsNone(poll_participation_gateway_provider(_Registry(object())))
        self.assertIsNone(poll_participation_gateway_provider(None))


if __name__ == "__main__":
    unittest.main()
