"""Agent Identity — identity layer for CyberBrain26 agents.

Every agent in the system MUST have an AgentIdentity. Identity enables:
- unique agent identification
- role determination
- tool permission scoping
- auditability of agent actions
- downstream credential scoping
- separation of agent from user

Agent MUST NOT automatically inherit all user permissions.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum
from typing import Any


class TrustLevel(str, Enum):
    """Trust level of an agent identity."""

    UNTRUSTED = "untrusted"
    VERIFIED = "verified"
    TRUSTED = "trusted"
    OFFICIAL = "official"


class AgentRole(str, Enum):
    """Built-in agent roles. Custom roles can be added via string values."""

    PLANNER = "planner"
    CODER = "coder"
    EVALUATOR = "evaluator"
    SECURITY = "security"
    RESEARCH = "research"
    SUPERVISOR = "supervisor"
    ROUTER = "router"
    BROWSER = "browser"
    COMPLIANCE = "compliance"
    CUSTOM = "custom"


class PermissionScope(str, Enum):
    """Standard permission scopes granted to an agent."""

    READ_FILE = "read_file"
    WRITE_FILE = "write_file"
    DELETE_FILE = "delete_file"
    NETWORK = "network"
    BROWSER = "browser"
    SHELL = "shell"
    PYTHON = "python"
    GIT = "git"
    DOCKER = "docker"
    SECRETS = "secrets"
    MCP = "mcp"
    AUDIT = "audit"


@dataclass
class AgentIdentity:
    """Identity of an agent within the CyberBrain26 system.

    Attributes:
        agent_id: Unique identifier for the agent instance.
        role: The agent's role (planner, coder, etc.).
        trust_level: Trust classification of the agent.
        scopes: Set of permission scopes granted to this identity.
        owner: User or system that owns this agent.
        metadata: Additional identity metadata (provider, version, etc.).
    """

    agent_id: str
    role: str
    trust_level: TrustLevel = TrustLevel.VERIFIED
    scopes: set[str] = field(default_factory=set)
    owner: str | None = None
    metadata: dict[str, Any] = field(default_factory=dict)

    def __post_init__(self) -> None:
        if not self.agent_id:
            raise ValueError("agent_id must not be empty")
        if not self.role:
            raise ValueError("role must not be empty")

    def has_scope(self, scope: str) -> bool:
        """Check whether this identity has a specific permission scope."""
        return scope in self.scopes

    def has_any_scope(self, scopes: set[str]) -> bool:
        """Check whether this identity has any of the given scopes."""
        return bool(scopes & self.scopes)

    def can_read_file(self) -> bool:
        return self.has_scope(PermissionScope.READ_FILE.value)

    def can_write_file(self) -> bool:
        return self.has_scope(PermissionScope.WRITE_FILE.value)

    def can_execute_shell(self) -> bool:
        return self.has_scope(PermissionScope.SHELL.value)

    def can_access_network(self) -> bool:
        return self.has_scope(PermissionScope.NETWORK.value)

    def can_access_secrets(self) -> bool:
        return self.has_scope(PermissionScope.SECRETS.value)

    def is_trusted(self) -> bool:
        return self.trust_level in (TrustLevel.TRUSTED, TrustLevel.OFFICIAL)


__all__ = [
    "AgentIdentity",
    "AgentRole",
    "PermissionScope",
    "TrustLevel",
]