"""add_data_ingestion_sources

Creates the data_ingestion_sources table for persistent source CRUD.
Replaces the derived-from-workflow-history approach.

Revision ID: add_data_ingestion_sources
Revises: add_task_hierarchy
Create Date: 2026-02-11 10:00:00.000000

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision: str = 'add_data_ingestion_sources'
down_revision: Union[str, Sequence[str], None] = 'add_task_hierarchy'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    """Create data_ingestion_sources table with enums, indexes, and constraints."""

    # Create enum types
    credential_method_enum = postgresql.ENUM(
        'integration', 'secret', 'inline',
        name='credentialmethod',
        create_type=False,
    )
    credential_method_enum.create(op.get_bind(), checkfirst=True)

    schedule_type_enum = postgresql.ENUM(
        'manual', 'cron',
        name='scheduletype',
        create_type=False,
    )
    schedule_type_enum.create(op.get_bind(), checkfirst=True)

    data_ingestion_source_status_enum = postgresql.ENUM(
        'active', 'inactive', 'error', 'deleted',
        name='dataingestionsourcestatus',
        create_type=False,
    )
    data_ingestion_source_status_enum.create(op.get_bind(), checkfirst=True)

    # Create table
    op.create_table(
        'data_ingestion_sources',
        sa.Column('id', postgresql.UUID(as_uuid=False), server_default=sa.text('gen_random_uuid()'), primary_key=True),
        sa.Column('organization_id', sa.String(255), nullable=False),
        sa.Column('name', sa.String(255), nullable=False),
        sa.Column('description', sa.Text(), nullable=True),
        sa.Column('intel_type', sa.String(100), nullable=False),
        sa.Column('credential_method', credential_method_enum, nullable=False),
        sa.Column('credential_ref', sa.String(500), nullable=True),
        sa.Column('config', postgresql.JSONB(astext_type=sa.Text()), nullable=False, server_default=sa.text("'{}'::jsonb")),
        sa.Column('schedule_type', schedule_type_enum, nullable=False, server_default='manual'),
        sa.Column('cron_expression', sa.String(100), nullable=True),
        sa.Column('status', data_ingestion_source_status_enum, nullable=False, server_default='active'),
        sa.Column('last_sync_at', sa.DateTime(timezone=True), nullable=True),
        sa.Column('last_sync_status', sa.String(50), nullable=True),
        sa.Column('last_sync_workflow_id', sa.String(500), nullable=True),
        sa.Column('last_error', sa.Text(), nullable=True),
        sa.Column('total_runs', sa.Integer(), nullable=False, server_default=sa.text('0')),
        sa.Column('success_count', sa.Integer(), nullable=False, server_default=sa.text('0')),
        sa.Column('failure_count', sa.Integer(), nullable=False, server_default=sa.text('0')),
        sa.Column('tags', postgresql.JSONB(astext_type=sa.Text()), nullable=True, server_default=sa.text("'[]'::jsonb")),
        sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
        sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
        sa.Column('created_by', sa.String(255), nullable=True),
        # Check constraints
        sa.CheckConstraint("name != ''", name='ck_di_source_name_not_empty'),
        sa.CheckConstraint("intel_type != ''", name='ck_di_source_intel_type_not_empty'),
    )

    # Create indexes
    op.create_index('ix_data_ingestion_sources_organization_id', 'data_ingestion_sources', ['organization_id'])
    op.create_index('idx_di_sources_org_name', 'data_ingestion_sources', ['organization_id', 'name'], unique=True)
    op.create_index('idx_di_sources_org_intel', 'data_ingestion_sources', ['organization_id', 'intel_type'])
    op.create_index('idx_di_sources_status', 'data_ingestion_sources', ['status'])
    op.create_index('idx_di_sources_org_status', 'data_ingestion_sources', ['organization_id', 'status'])

    print("Created data_ingestion_sources table with indexes and constraints")


def downgrade() -> None:
    """Drop data_ingestion_sources table and enum types."""

    op.drop_index('idx_di_sources_org_status', table_name='data_ingestion_sources')
    op.drop_index('idx_di_sources_status', table_name='data_ingestion_sources')
    op.drop_index('idx_di_sources_org_intel', table_name='data_ingestion_sources')
    op.drop_index('idx_di_sources_org_name', table_name='data_ingestion_sources')
    op.drop_index('ix_data_ingestion_sources_organization_id', table_name='data_ingestion_sources')

    op.drop_table('data_ingestion_sources')

    # Drop enum types
    op.execute("DROP TYPE IF EXISTS dataingestionourcestatus")
    op.execute("DROP TYPE IF EXISTS credentialmethod")
    op.execute("DROP TYPE IF EXISTS scheduletype")

    print("Dropped data_ingestion_sources table and enum types")
