"""Tests for domain models."""

from __future__ import annotations

from datetime import datetime, timezone

from vault.models import (
    AccessPolicy,
    Secret,
    SecretCreateRequest,
    SecretMetadata,
    SecretVersion,
)


class TestAccessPolicy:
    def test_empty_policy_allows_everything(self):
        policy = AccessPolicy()
        assert policy.allows(service="any", role="any")

    def test_allowed_service(self):
        policy = AccessPolicy(allowed_services=["api-gateway", "worker"])
        assert policy.allows(service="api-gateway")
        assert not policy.allows(service="unknown-service")

    def test_allowed_role(self):
        policy = AccessPolicy(allowed_roles=["admin", "devops"])
        assert policy.allows(role="admin")
        assert not policy.allows(role="viewer")

    def test_combined_check(self):
        policy = AccessPolicy(allowed_services=["api"], allowed_roles=["admin"])
        assert policy.allows(service="api", role="admin")
        assert not policy.allows(service="api", role="viewer")
        assert not policy.allows(service="other", role="admin")


class TestSecretVersion:
    def test_defaults(self):
        v = SecretVersion(version_number=1, encrypted_value=b"enc")
        assert v.version_number == 1
        assert v.created_by == ""
        assert v.created_at is not None


class TestSecret:
    def test_defaults(self):
        s = Secret(id="abc", name="db-password", encrypted_value=b"enc")
        assert s.version == 1
        assert s.deleted is False
        assert s.tags == {}
        assert s.versions == []

    def test_with_tags_and_policy(self):
        policy = AccessPolicy(allowed_services=["backend"])
        s = Secret(
            id="123",
            name="api-key",
            encrypted_value=b"enc",
            tags={"env": "prod"},
            access_policy=policy,
        )
        assert s.tags["env"] == "prod"
        assert s.access_policy.allowed_services == ["backend"]


class TestSecretMetadata:
    def test_from_secret(self):
        now = datetime.now(timezone.utc)
        s = Secret(
            id="x",
            name="test",
            encrypted_value=b"hidden",
            version=3,
            tags={"team": "platform"},
            created_at=now,
            updated_at=now,
        )
        meta = SecretMetadata.from_secret(s)
        assert meta.name == "test"
        assert meta.version == 3
        assert meta.tags == {"team": "platform"}
        # Metadata should not expose the encrypted value
        assert not hasattr(meta, "encrypted_value")


class TestSecretCreateRequest:
    def test_minimal(self):
        req = SecretCreateRequest(name="token", value="secret123")
        assert req.name == "token"
        assert req.tags == {}
        assert req.allowed_services == []
