"""
Data Ingestion Source Model

Persistent entity for data ingestion sources that sync external platform data
(AWS, GitHub, Azure, etc.) into the Context Graph via Temporal workflows.

Replaces the previous derived-from-workflow-history approach with proper CRUD.
"""
from sqlalchemy import Column, String, DateTime, Text, Integer, Enum, Index, CheckConstraint, text, func
from sqlalchemy.dialects.postgresql import UUID, JSONB
import enum

from control_plane_api.app.database import Base


class DataIngestionSourceStatus(str, enum.Enum):
    """Ingestion source lifecycle status"""
    ACTIVE = "active"
    INACTIVE = "inactive"
    ERROR = "error"
    DELETED = "deleted"


class CredentialMethod(str, enum.Enum):
    """How credentials are provided for an ingestion source"""
    INTEGRATION = "integration"
    SECRET = "secret"
    INLINE = "inline"


class ScheduleType(str, enum.Enum):
    """Schedule type for recurring ingestion"""
    MANUAL = "manual"
    CRON = "cron"


class DataIngestionSource(Base):
    """
    Persistent data ingestion source.

    Each source represents a configured connection to an external platform
    (e.g. AWS, GitHub) that syncs data into the Context Graph. Sources own
    their credential references, schedule config, and sync statistics.
    """
    __tablename__ = "data_ingestion_sources"

    id = Column(UUID(as_uuid=False), primary_key=True, server_default=text("gen_random_uuid()"))
    organization_id = Column(String(255), nullable=False, index=True)

    # Identification
    name = Column(String(255), nullable=False)
    description = Column(Text, nullable=True)
    intel_type = Column(String(100), nullable=False)  # aws, azure, github, etc.

    # Credentials
    credential_method = Column(Enum(CredentialMethod), nullable=False)
    credential_ref = Column(String(500), nullable=True)  # integration_id or secret_name

    # Configuration
    config = Column(JSONB, nullable=False, server_default=text("'{}'::jsonb"))

    # Schedule
    schedule_type = Column(Enum(ScheduleType), nullable=False, server_default="manual")
    cron_expression = Column(String(100), nullable=True)

    # Status
    status = Column(Enum(DataIngestionSourceStatus), nullable=False, server_default="active")

    # Sync tracking
    last_sync_at = Column(DateTime(timezone=True), nullable=True)
    last_sync_status = Column(String(50), nullable=True)  # success/failed/running
    last_sync_workflow_id = Column(String(500), nullable=True)
    last_error = Column(Text, nullable=True)

    # Statistics
    total_runs = Column(Integer, nullable=False, server_default=text("0"))
    success_count = Column(Integer, nullable=False, server_default=text("0"))
    failure_count = Column(Integer, nullable=False, server_default=text("0"))

    # Metadata
    tags = Column(JSONB, nullable=True, server_default=text("'[]'::jsonb"))
    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
    created_by = Column(String(255), nullable=True)

    # Constraints and indexes
    __table_args__ = (
        Index("idx_di_sources_org_name", "organization_id", "name", unique=True),
        Index("idx_di_sources_org_intel", "organization_id", "intel_type"),
        Index("idx_di_sources_status", "status"),
        Index("idx_di_sources_org_status", "organization_id", "status"),
        CheckConstraint("name != ''", name="ck_di_source_name_not_empty"),
        CheckConstraint("intel_type != ''", name="ck_di_source_intel_type_not_empty"),
    )

    def __repr__(self):
        return f"<DataIngestionSource(id={self.id}, name={self.name}, intel_type={self.intel_type})>"
