"""Pydantic models for delegation lifecycle.

Originally from llm-principal-broker (GCAP-SPEC-LLM-PRINCIPAL-BROKER-0001
§3, §8). Absorbed into fastapi-gsap as the delegations submodule so that
the lifecycle bookkeeping shares process and database with the AC issuance
endpoints. The previous standalone service made an HTTP call back to GSAP
on every delegation creation; now it is an in-process function call.
"""

from pydantic import BaseModel, Field
from typing import Optional
from enum import Enum


class DelegationStatus(str, Enum):
    REQUESTED = "requested"
    ACTIVE = "active"
    EXPIRED = "expired"
    REVOKED = "revoked"


class DelegationScope(BaseModel):
    inherit_corpus: bool = True
    inherit_contexts: bool = True
    capability_ceiling: str = "CAP_MUTATE"
    ceremony_required_for: list[str] = Field(
        default_factory=lambda: ["delete", "destroy", "drop"]
    )
    prohibited_commands: list[str] = Field(default_factory=list)
    max_ttl_minutes: int = 60
    max_commands: int = 500


class DelegationRequest(BaseModel):
    """POST /delegations/ request body — §8.1."""
    delegator_ac_id: str
    agent_type: str = "claude-code"
    agent_model: Optional[str] = None
    scope: Optional[DelegationScope] = None
    accord_template: str = "ai-delegation-standard"


class AgentPrincipal(BaseModel):
    did: str
    keycloak_client_id: str
    display_name: str


class DelegationResponse(BaseModel):
    """POST /delegations/ response — §3.2."""
    delegation_id: str
    agent_principal: AgentPrincipal
    delegated_ac: dict
    agent_token: str
    expires_at: str
    max_commands: int
    chronicle_cid: Optional[str] = None


class DelegationInfo(BaseModel):
    """GET /delegations/{id} response — §8.3."""
    delegation_id: str
    status: DelegationStatus
    agent_did: str
    agent_type: str
    delegator_did: str
    commands_executed: int
    commands_remaining: int
    ttl_remaining_seconds: int
    created_at: str
    expires_at: str


class RevokeRequest(BaseModel):
    reason: str = "manual_revocation"


class RevokeResponse(BaseModel):
    delegation_id: str
    status: str = "revoked"
    reason: str
    chronicle_cid: Optional[str] = None


class ActiveDelegation(BaseModel):
    delegation_id: str
    agent_type: str
    delegator: str
    commands_executed: int
    ttl_remaining_seconds: int
    status: str


class AgentListResponse(BaseModel):
    active_delegations: list[ActiveDelegation]
    total_active: int
