"""rename grandagent to grace_orchestrator

Revision ID: 9d3f2e4b7a11
Revises: 45d46ebab0e2
Create Date: 2026-02-09 12:05:00.000000

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '9d3f2e4b7a11'
down_revision: Union[str, Sequence[str], None] = '45d46ebab0e2'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def _get_agent_by_name(conn: sa.engine.Connection, name: str):
    return conn.execute(
        sa.text(
            """
            SELECT id, name
            FROM agent
            WHERE name = :name
            LIMIT 1
            """
        ),
        {"name": name},
    ).mappings().first()


def _get_legacy_grace_agent(conn: sa.engine.Connection):
    return conn.execute(
        sa.text(
            """
            SELECT id, name
            FROM agent
            WHERE name LIKE 'grace_orchestrator_legacy_%'
            ORDER BY id
            LIMIT 1
            """
        )
    ).mappings().first()


def upgrade() -> None:
    """Upgrade schema."""
    conn = op.get_bind()

    grandagent = _get_agent_by_name(conn, "grandagent")
    grace_orchestrator = _get_agent_by_name(conn, "grace_orchestrator")

    # Already migrated or no relevant data to migrate.
    if grandagent is None:
        return

    # If a grace_orchestrator row already exists (e.g., seeded by newer code),
    # move it out of the way so we can preserve the existing grandagent row
    # and all of its profile/version relationships.
    if grace_orchestrator is not None:
        legacy_name = f"grace_orchestrator_legacy_{grace_orchestrator['id']}"
        conn.execute(
            sa.text(
                """
                UPDATE agent
                SET name = :legacy_name,
                    updated_at = now()
                WHERE id = :agent_id
                """
            ),
            {"legacy_name": legacy_name, "agent_id": grace_orchestrator["id"]},
        )

    conn.execute(
        sa.text(
            """
            UPDATE agent
            SET name = 'grace_orchestrator',
                updated_at = now()
            WHERE id = :agent_id
            """
        ),
        {"agent_id": grandagent["id"]},
    )


def downgrade() -> None:
    """Downgrade schema."""
    conn = op.get_bind()

    grandagent = _get_agent_by_name(conn, "grandagent")
    grace_orchestrator = _get_agent_by_name(conn, "grace_orchestrator")

    # Revert canonical rename when possible.
    if grace_orchestrator is not None and grandagent is None:
        conn.execute(
            sa.text(
                """
                UPDATE agent
                SET name = 'grandagent',
                    updated_at = now()
                WHERE id = :agent_id
                """
            ),
            {"agent_id": grace_orchestrator["id"]},
        )

    # If upgrade had to move aside an existing grace_orchestrator row,
    # restore it on downgrade.
    legacy = _get_legacy_grace_agent(conn)
    grace_after = _get_agent_by_name(conn, "grace_orchestrator")
    if legacy is not None and grace_after is None:
        conn.execute(
            sa.text(
                """
                UPDATE agent
                SET name = 'grace_orchestrator',
                    updated_at = now()
                WHERE id = :agent_id
                """
            ),
            {"agent_id": legacy["id"]},
        )
