"""
Type-safe schemas for registry sync communication.

This module defines Pydantic models used to serialize/deserialize data
for registry sync operations, including:
- Subprocess sync (existing)
- Temporal workflow sync (sandboxed executor)
"""

from __future__ import annotations

from typing import Literal
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field, TypeAdapter

from tracecat.registry.actions.schemas import (
    RegistryActionCreate,
    RegistryActionValidationErrorInfo,
)


class SyncResultSuccess(BaseModel):
    """Successful sync result containing actions and metadata."""

    actions: list[RegistryActionCreate] = Field(
        default_factory=list,
        description="List of serialized registry actions.",
    )
    commit_sha: str | None = Field(
        default=None,
        description="The resolved commit SHA (None for local/builtin repos).",
    )
    validation_errors: dict[str, list[RegistryActionValidationErrorInfo]] = Field(
        default_factory=dict,
        description="Map of action name to list of validation errors.",
    )


class SyncResultError(BaseModel):
    """Error result from sync subprocess."""

    error: str = Field(..., description="Error message from the subprocess.")


# Type adapter for parsing the sync result (success or error)
SyncResultAdapter: TypeAdapter[SyncResultSuccess | SyncResultError] = TypeAdapter(
    SyncResultSuccess | SyncResultError
)


# =============================================================================
# Temporal Workflow Schemas (Sandboxed Registry Sync)
# =============================================================================


class RegistrySyncRequest(BaseModel):
    """Request for sandboxed registry sync via Temporal workflow.

    This is passed from the API service to the ExecutorWorker via Temporal.
    Git SSH keys are fetched by the ExecutorWorker and never enter Temporal args.
    """

    model_config = ConfigDict(extra="ignore")

    repository_id: UUID = Field(..., description="Database repository ID")
    origin: str = Field(..., description="Repository origin URL or name")
    origin_type: Literal["builtin", "local", "git"] = Field(
        ..., description="Type of repository origin"
    )
    git_url: str | None = Field(
        default=None, description="Git SSH URL for cloning (git origins only)"
    )
    commit_sha: str | None = Field(
        default=None, description="Target commit SHA (git origins only)"
    )
    git_repo_package_name: str | None = Field(
        default=None,
        description="Optional Python package name override for git repositories",
    )
    validate_actions: bool = Field(
        default=False, description="Whether to validate template actions"
    )
    storage_namespace: str | None = Field(
        default=None,
        description=(
            "Storage namespace for tarball uploads (e.g., org ID or 'platform'). "
            "Defaults to the deployment's default org ID when not provided."
        ),
    )
    organization_id: UUID | None = Field(
        default=None,
        description="Organization ID for org-scoped operations (e.g., secrets access).",
    )


class RegistrySyncResult(BaseModel):
    """Result from sandboxed registry sync workflow.

    Returned from the ExecutorWorker to the API service via Temporal.
    Contains discovered actions and tarball location for DB operations.
    """

    actions: list[RegistryActionCreate] = Field(
        default_factory=list,
        description="List of discovered registry actions",
    )
    tarball_uri: str = Field(..., description="S3 URI of the uploaded tarball venv")
    commit_sha: str | None = Field(
        default=None,
        description="Resolved commit SHA (None for builtin/local repos)",
    )
    validation_errors: dict[str, list[RegistryActionValidationErrorInfo]] = Field(
        default_factory=dict,
        description="Map of action name to validation errors",
    )


class RegistryArtifactsBackfillItem(BaseModel):
    """Registry version whose artifacts should be backfilled."""

    version_id: UUID = Field(..., description="Database registry version ID")
    version: str = Field(..., description="Registry version string")
    tarball_uri: str = Field(..., description="S3 URI of the existing tarball venv")


class RegistryArtifactsBackfillRequest(BaseModel):
    """Request for backfilling registry version artifacts."""

    items: list[RegistryArtifactsBackfillItem] = Field(
        ..., min_length=1, description="Registry versions to backfill"
    )


class RegistryArtifactsBackfillItemResult(BaseModel):
    """Result for one registry version artifact backfill."""

    version_id: UUID
    status: Literal["created", "exists", "skipped", "failed"]
    error: str | None = None


class RegistryArtifactsBackfillResult(BaseModel):
    """Result from a registry artifact backfill workflow."""

    requested_count: int
    results: list[RegistryArtifactsBackfillItemResult]
