"""Add agent_enabled column to collections

Gives each RAG collection a usability switch: should it be offered to the
research agent (LangGraph) as a specialized search tool? Defaults to True
(available) so existing collections keep their current behaviour. Flip it off
to declutter the agent's tool list when a collection isn't needed for agentic
research. This is independent of is_public / egress scope — a usability flag,
NOT a security control.

Revision ID: 0012
Revises: 0011
Create Date: 2026-06-07

Column Added:
=============
- agent_enabled (BOOLEAN, nullable): Whether the collection is exposed to the
  LangGraph research agent as a search tool. The column is nullable, but
  effectively non-null for new rows via server_default=1 (available); any
  legacy NULL is treated as available at the loader (NULL → True), so
  pre-existing collections stay available — behaviour-preserving.

Migration Notes:
===============
- Uses SQLite batch mode (table recreation) for ALTER TABLE operations.
- Idempotent: skips the column if it already exists (fresh databases created
  after the model change will already have it).

Downgrade Behavior:
==================
The downgrade() function removes the agent_enabled column. Any per-collection
agent-availability choice will be LOST on downgrade.
"""

from alembic import op
import sqlalchemy as sa
from sqlalchemy import inspect

# revision identifiers, used by Alembic.
revision = "0012"
down_revision = "0011"
branch_labels = None
depends_on = None


def column_exists(table_name: str, column_name: str) -> bool:
    """Check if a column exists in a table."""
    bind = op.get_bind()
    inspector = inspect(bind)

    if not inspector.has_table(table_name):
        return False

    columns = {col["name"] for col in inspector.get_columns(table_name)}
    return column_name in columns


def upgrade():
    """Add agent_enabled column to collections if it doesn't exist."""
    bind = op.get_bind()
    inspector = inspect(bind)

    if not inspector.has_table("collections"):
        # Table doesn't exist yet, will be created by initial migration
        return

    if column_exists("collections", "agent_enabled"):
        # Column already exists (fresh database created after model change)
        return

    # Use batch mode for SQLite compatibility. server_default 1 so existing
    # collections stay available to the agent (behaviour-preserving) without a
    # separate backfill UPDATE. nullable=True to match the ORM model column
    # (Collection.agent_enabled, like its sibling is_public, is nullable) so the
    # schema-drift autogenerate check stays clean; the loader treats NULL as
    # available (True) anyway.
    with op.batch_alter_table("collections") as batch_op:
        batch_op.add_column(
            sa.Column(
                "agent_enabled",
                sa.Boolean(),
                nullable=True,
                server_default=sa.true(),
            )
        )


def downgrade():
    """Remove agent_enabled column from collections."""
    bind = op.get_bind()
    inspector = inspect(bind)

    if not inspector.has_table("collections"):
        return

    if not column_exists("collections", "agent_enabled"):
        return

    with op.batch_alter_table("collections") as batch_op:
        batch_op.drop_column("agent_enabled")
