"""Tests for permission matching."""

import pytest

from vikdata_auth.permissions import (
    has_all_permissions,
    has_any_permission,
    has_permission,
    match_permission,
)


class TestMatchPermission:
    """Tests for match_permission function."""

    def test_exact_match(self):
        """Exact permission matches."""
        assert match_permission("vessels:read", "vessels:read") is True
        assert match_permission("vessels:write", "vessels:read") is False

    def test_super_admin_wildcard(self):
        """*:* matches everything."""
        assert match_permission("*:*", "vessels:read") is True
        assert match_permission("*:*", "users:write") is True
        assert match_permission("*:*", "anything:here") is True

    def test_action_wildcard(self):
        """resource:* matches any action on that resource."""
        assert match_permission("vessels:*", "vessels:read") is True
        assert match_permission("vessels:*", "vessels:write") is True
        assert match_permission("vessels:*", "vessels:delete") is True
        assert match_permission("vessels:*", "users:read") is False

    def test_resource_wildcard(self):
        """*:action matches that action on any resource."""
        assert match_permission("*:read", "vessels:read") is True
        assert match_permission("*:read", "users:read") is True
        assert match_permission("*:read", "vessels:write") is False

    def test_no_colon_in_permission(self):
        """Permissions without colon only match exactly."""
        assert match_permission("admin", "admin") is True
        assert match_permission("admin", "user") is False
        assert match_permission("admin", "admin:read") is False

    def test_empty_permissions(self):
        """Empty strings don't match anything."""
        assert match_permission("", "vessels:read") is False
        assert match_permission("vessels:read", "") is False


class TestHasPermission:
    """Tests for has_permission function."""

    def test_empty_permissions_list(self):
        """Empty permission list grants nothing."""
        assert has_permission([], "vessels:read") is False

    def test_single_matching_permission(self):
        """Single matching permission grants access."""
        assert has_permission(["vessels:read"], "vessels:read") is True

    def test_single_non_matching_permission(self):
        """Single non-matching permission denies access."""
        assert has_permission(["vessels:write"], "vessels:read") is False

    def test_multiple_permissions_with_match(self):
        """Multiple permissions with one match grants access."""
        perms = ["users:read", "vessels:read", "vessels:write"]
        assert has_permission(perms, "vessels:read") is True

    def test_wildcard_in_list(self):
        """Wildcard in permission list grants access."""
        assert has_permission(["*:*"], "vessels:read") is True
        assert has_permission(["vessels:*"], "vessels:read") is True
        assert has_permission(["*:read"], "vessels:read") is True


class TestHasAnyPermission:
    """Tests for has_any_permission function."""

    def test_has_one_of_multiple(self):
        """Having one of multiple required permissions grants access."""
        user_perms = ["vessels:read"]
        required = ["vessels:read", "vessels:write"]
        assert has_any_permission(user_perms, required) is True

    def test_has_none_of_multiple(self):
        """Having none of multiple required permissions denies access."""
        user_perms = ["users:read"]
        required = ["vessels:read", "vessels:write"]
        assert has_any_permission(user_perms, required) is False

    def test_wildcard_matches_any(self):
        """Wildcard matches any of the required permissions."""
        user_perms = ["vessels:*"]
        required = ["vessels:read", "vessels:delete"]
        assert has_any_permission(user_perms, required) is True

    def test_empty_required_list(self):
        """Empty required list returns False (no permission to match)."""
        assert has_any_permission(["vessels:read"], []) is False


class TestHasAllPermissions:
    """Tests for has_all_permissions function."""

    def test_has_all(self):
        """Having all required permissions grants access."""
        user_perms = ["vessels:read", "vessels:write", "users:read"]
        required = ["vessels:read", "vessels:write"]
        assert has_all_permissions(user_perms, required) is True

    def test_missing_one(self):
        """Missing one required permission denies access."""
        user_perms = ["vessels:read"]
        required = ["vessels:read", "vessels:write"]
        assert has_all_permissions(user_perms, required) is False

    def test_wildcard_covers_all(self):
        """Wildcard can cover multiple required permissions."""
        user_perms = ["vessels:*"]
        required = ["vessels:read", "vessels:write", "vessels:delete"]
        assert has_all_permissions(user_perms, required) is True

    def test_super_admin_covers_all(self):
        """Super admin wildcard covers all permissions."""
        user_perms = ["*:*"]
        required = ["vessels:read", "users:write", "admin:delete"]
        assert has_all_permissions(user_perms, required) is True

    def test_empty_required_list(self):
        """Empty required list returns True (vacuously true)."""
        assert has_all_permissions(["vessels:read"], []) is True
