from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Literal


GroupPolicyDefault = Literal["automatic", "manual", "mixed"]
ServiceStyle = Literal["event_driven", "periodic", "hybrid"]


@dataclass(frozen=True)
class Declaration:
    """
    v1 DSL declaration template.

    Declaration objects only carry metadata/defaults and never perform runtime
    registration/deployment side effects.
    """

    target: Any
    uri: str | None = None
    description: str | None = None
    tags: tuple[str, ...] = ()
    capabilities: tuple[str, ...] = ()
    input_schema_ref: str | None = None
    output_schema_ref: str | None = None
    resources_default: dict[str, Any] = field(default_factory=dict)
    scheduler_default: dict[str, Any] = field(default_factory=dict)
    policies: dict[str, Any] = field(default_factory=dict)
    metadata: dict[str, Any] = field(default_factory=dict)
    dsl_name: str | None = None

    def __get__(self, instance, owner):
        if instance is not None:
            raise TypeError(
                f"v1 {type(self).__name__} does not support class-instance binding. "
                "Define DSL as module/static symbol.",
            )
        return self


@dataclass(frozen=True)
class SourceDeclaration(Declaration):
    checkpoint_required: bool = True
    group_policy_default: GroupPolicyDefault = "automatic"
    cursor_format: str | None = None


@dataclass(frozen=True)
class ServiceDeclaration(Declaration):
    service_style: ServiceStyle = "event_driven"
    heartbeat_default_sec: float | None = None


@dataclass(frozen=True)
class ProcessDeclaration(Declaration):
    kind: str = ""


@dataclass(frozen=True)
class ActorDeclaration(Declaration):
    mailbox_policy_default: dict[str, Any] = field(default_factory=dict)
    execution_policy_default: dict[str, Any] = field(default_factory=dict)
    retry_policy_default: dict[str, Any] = field(default_factory=dict)
    admission_policy_default: dict[str, Any] = field(default_factory=dict)
    drain_policy_default: dict[str, Any] = field(default_factory=dict)


@dataclass(frozen=True)
class StatelessDeclaration(Declaration):
    pass


__all__ = [
    "ActorDeclaration",
    "Declaration",
    "GroupPolicyDefault",
    "ProcessDeclaration",
    "ServiceDeclaration",
    "ServiceStyle",
    "SourceDeclaration",
    "StatelessDeclaration",
]
