# #region TestPolicyResolutionService [C:2] [TYPE Module]
# @SEMANTICS: clean-release, policy-resolution, trusted-snapshots, contracts
# @PURPOSE: Verify trusted policy snapshot resolution contract and error guards.
# @LAYER Tests
# @RELATION  DEPENDS_ON -> [EXT:frontend:policy_resolution_service]
# @RELATION  DEPENDS_ON -> [EXT:frontend:repository]
# @RELATION  DEPENDS_ON -> [clean_release_exceptions]
# @INVARIANT: Resolution uses only ConfigManager active IDs and rejects runtime override attempts.

from __future__ import annotations

import pytest
from types import SimpleNamespace

from src.models.clean_release import CleanPolicySnapshot, SourceRegistrySnapshot
from src.services.clean_release.exceptions import PolicyResolutionError
from src.services.clean_release.policy_resolution_service import (
    resolve_trusted_policy_snapshots,
)
from src.services.clean_release.repository import CleanReleaseRepository


# #region _config_manager [C:2] [TYPE Function]
# @RELATION  BINDS_TO -> [EXT:frontend:TestPolicyResolutionService]
# @PURPOSE: Build deterministic ConfigManager-like stub for tests.
# @INVARIANT: Only settings.clean_release.active_policy_id and active_registry_id are populated; any other settings field access raises AttributeError.
# @PRE: policy_id and registry_id may be None or non-empty strings.
# @POST: Returns object exposing get_config().settings.clean_release active IDs.
def _config_manager(policy_id, registry_id):
    clean_release = SimpleNamespace(
        active_policy_id=policy_id, active_registry_id=registry_id
    )
    settings = SimpleNamespace(clean_release=clean_release)
    config = SimpleNamespace(settings=settings)
    return SimpleNamespace(get_config=lambda: config)


# #endregion _config_manager


# #region test_resolve_trusted_policy_snapshots_missing_profile [C:2] [TYPE Function]
# @RELATION  BINDS_TO -> [EXT:frontend:TestPolicyResolutionService]
# @PURPOSE: Ensure resolution fails when trusted profile is not configured.
# @PRE: active_policy_id is None.
# @POST: Raises PolicyResolutionError with missing trusted profile reason.
def test_resolve_trusted_policy_snapshots_missing_profile():
    repository = CleanReleaseRepository()
    config_manager = _config_manager(policy_id=None, registry_id="registry-1")

    with pytest.raises(PolicyResolutionError, match="missing trusted profile"):
        resolve_trusted_policy_snapshots(
            config_manager=config_manager,
            repository=repository,
        )


# #endregion test_resolve_trusted_policy_snapshots_missing_profile


# #region test_resolve_trusted_policy_snapshots_missing_registry [C:2] [TYPE Function]
# @RELATION  BINDS_TO -> [EXT:frontend:TestPolicyResolutionService]
# @PURPOSE: Ensure resolution fails when trusted registry is not configured.
# @PRE: active_registry_id is None and active_policy_id is set.
# @POST: Raises PolicyResolutionError with missing trusted registry reason.
def test_resolve_trusted_policy_snapshots_missing_registry():
    repository = CleanReleaseRepository()
    config_manager = _config_manager(policy_id="policy-1", registry_id=None)

    with pytest.raises(PolicyResolutionError, match="missing trusted registry"):
        resolve_trusted_policy_snapshots(
            config_manager=config_manager,
            repository=repository,
        )


# #endregion test_resolve_trusted_policy_snapshots_missing_registry


# #region test_resolve_trusted_policy_snapshots_rejects_override_attempt [C:2] [TYPE Function]
# @RELATION  BINDS_TO -> [EXT:frontend:TestPolicyResolutionService]
# @PURPOSE: Ensure runtime override attempt is rejected even if snapshots exist.
# @PRE: valid trusted snapshots exist in repository and override is provided.
# @POST: Raises PolicyResolutionError with override forbidden reason.
def test_resolve_trusted_policy_snapshots_rejects_override_attempt():
    repository = CleanReleaseRepository()
    repository.save_policy(
        CleanPolicySnapshot(
            id="policy-1",
            policy_id="baseline",
            policy_version="1.0.0",
            content_json={"rules": []},
            registry_snapshot_id="registry-1",
            immutable=True,
        )
    )
    repository.save_registry(
        SourceRegistrySnapshot(
            id="registry-1",
            registry_id="trusted",
            registry_version="1.0.0",
            allowed_hosts=["internal.local"],
            allowed_schemes=["https"],
            allowed_source_types=["repo"],
            immutable=True,
        )
    )

    config_manager = _config_manager(policy_id="policy-1", registry_id="registry-1")

    with pytest.raises(PolicyResolutionError, match="override attempt is forbidden"):
        resolve_trusted_policy_snapshots(
            config_manager=config_manager,
            repository=repository,
            policy_id_override="policy-override",
        )


# #endregion test_resolve_trusted_policy_snapshots_rejects_override_attempt

# #endregion TestPolicyResolutionService
