from __future__ import annotations

import unittest

from govoplan_core.core.access import PrincipalRef
from govoplan_core.core.modules import ModuleContext, ModuleManifest
from govoplan_core.core.policy import (
    CAPABILITY_POLICY_VIEW_GOVERNANCE,
    DefinitionScopeRef,
    ViewGovernanceDecision,
    ViewGovernancePolicy,
    ViewGovernanceRequest,
    view_governance_policy,
)
from govoplan_core.core.registry import PlatformRegistry


class _ViewPolicy:
    def resolve_view_action(self, session=None, *, request):
        del session
        return ViewGovernanceDecision(
            allowed=request.action != "assign",
            allowed_view_ids=frozenset(request.candidate_view_ids[:1]),
        )


class ViewGovernanceContractTests(unittest.TestCase):
    def test_policy_is_runtime_resolved_through_core_contract(self) -> None:
        provider = _ViewPolicy()
        self.assertIsInstance(provider, ViewGovernancePolicy)
        registry = PlatformRegistry()
        registry.register(
            ModuleManifest(
                id="view_governance_test",
                name="View governance test",
                version="test",
                capability_factories={
                    CAPABILITY_POLICY_VIEW_GOVERNANCE: lambda context: provider,
                },
            )
        )
        registry.configure_capability_context(
            ModuleContext(registry=registry, settings=object())
        )

        resolved = view_governance_policy(registry)
        self.assertIs(provider, resolved)
        decision = resolved.resolve_view_action(
            request=ViewGovernanceRequest(
                tenant_id="tenant-1",
                action="view",
                actor=PrincipalRef(
                    account_id="account-1",
                    membership_id=None,
                    tenant_id="tenant-1",
                ),
                target_scope=DefinitionScopeRef("user", "account-1"),
                candidate_view_ids=("view-1", "view-2"),
            )
        )

        self.assertTrue(decision.allowed)
        self.assertEqual(frozenset({"view-1"}), decision.allowed_view_ids)


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