# Copyright (C) 2026 Garudex Labs.  All Rights Reserved.
# Caracal, a product of Garudex Labs
#
# Caracal JWT claim shapes and verification configuration types.

from __future__ import annotations

from dataclasses import dataclass, field


# DEFAULT_MAX_HOP_COUNT caps delegation chain depth when verifier callers leave
# JwtConfig.max_hop_count unset. Matches the coordinator's MAX_DEPTH so a token
# that would have been blocked at spawn time cannot pass a permissive resource
# server.
DEFAULT_MAX_HOP_COUNT = 10
MANDATE_USE_SESSION = "session"
MANDATE_USE_RESOURCE = "resource"


@dataclass
class JwtConfig:
    issuer: str
    audience: str
    expected_zone_id: str | None = None
    required_scopes: list[str] = field(default_factory=list)
    required_targets: list[str] = field(default_factory=list)
    required_use: str | None = None
    require_agent: bool = False
    require_delegation: bool = False
    require_chain_contains: list[str] = field(default_factory=list)
    max_hop_count: int | None = None


@dataclass
class ChainHop:
    application_id: str
    agent_session_id: str | None = None
    delegation_edge_id: str | None = None


@dataclass
class Claims:
    sub: str
    zone_id: str
    client_id: str
    sid: str
    use: str
    jti: str
    scope: str
    issued_at: int
    expires_at: int
    target_resources: list[str] = field(default_factory=list)
    root_sid: str | None = None
    agent_session_id: str | None = None
    delegation_edge_id: str | None = None
    source_session_id: str | None = None
    target_session_id: str | None = None
    delegation_path: list[str] = field(default_factory=list)
    delegation_chain: list[ChainHop] = field(default_factory=list)
    graph_epoch: int | None = None
    hop_count: int | None = None
