"""phase 2 executions

Revision ID: 7e76a1a0dd21
Revises: e579fe82c6a7
"""
from collections.abc import Sequence

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

revision: str = '7e76a1a0dd21'
down_revision: str | Sequence[str] | None = 'e579fe82c6a7'
branch_labels = None
depends_on = None

def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('executions',
    sa.Column('id', sa.Uuid(), nullable=False),
    sa.Column('workspace_id', sa.Uuid(), nullable=False),
    sa.Column('requested_by_user_id', sa.Uuid(), nullable=False),
    sa.Column('instruction', sa.Text(), nullable=False),
    sa.Column('instruction_hash', sa.String(length=64), nullable=False),
    sa.Column('status', sa.String(length=32), nullable=False),
    sa.Column('provider', sa.String(length=40), nullable=True),
    sa.Column('model', sa.String(length=160), nullable=True),
    sa.Column('provider_response_id', sa.String(length=160), nullable=True),
    sa.Column('plan', sa.JSON().with_variant(postgresql.JSONB(astext_type=sa.Text()), 'postgresql'), nullable=True),
    sa.Column('output_summary', sa.Text(), nullable=True),
    sa.Column('error_code', sa.String(length=80), nullable=True),
    sa.Column('input_tokens', sa.Integer(), nullable=False),
    sa.Column('output_tokens', sa.Integer(), nullable=False),
    sa.Column('stop_requested_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('started_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
    sa.Column('version', sa.Integer(), nullable=False),
    sa.CheckConstraint("status IN ('planning','planned','awaiting_approval','running','succeeded','failed','cancelled','blocked','unknown')", name='ck_execution_status'),
    sa.CheckConstraint('input_tokens >= 0', name='ck_execution_input_tokens'),
    sa.CheckConstraint('output_tokens >= 0', name='ck_execution_output_tokens'),
    sa.CheckConstraint('version > 0', name='ck_execution_version'),
    sa.ForeignKeyConstraint(['workspace_id', 'requested_by_user_id'], ['workspace_memberships.workspace_id', 'workspace_memberships.user_id'], name='fk_execution_requester_membership'),
    sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('workspace_id', 'id', name='uq_execution_workspace_id')
    )
    op.create_index('ix_execution_workspace_status_created', 'executions', ['workspace_id', 'status', 'created_at'], unique=False)
    op.create_index(op.f('ix_executions_requested_by_user_id'), 'executions', ['requested_by_user_id'], unique=False)
    op.create_index(op.f('ix_executions_workspace_id'), 'executions', ['workspace_id'], unique=False)
    op.create_table('execution_steps',
    sa.Column('id', sa.Uuid(), nullable=False),
    sa.Column('workspace_id', sa.Uuid(), nullable=False),
    sa.Column('execution_id', sa.Uuid(), nullable=False),
    sa.Column('position', sa.Integer(), nullable=False),
    sa.Column('model_step_id', sa.String(length=80), nullable=False),
    sa.Column('tool_name', sa.String(length=120), nullable=False),
    sa.Column('permission', sa.String(length=120), nullable=False),
    sa.Column('risk', sa.String(length=16), nullable=False),
    sa.Column('access_type', sa.String(length=16), nullable=False),
    sa.Column('arguments', sa.JSON().with_variant(postgresql.JSONB(astext_type=sa.Text()), 'postgresql'), nullable=False),
    sa.Column('concise_rationale', sa.String(length=500), nullable=False),
    sa.Column('depends_on', sa.JSON().with_variant(postgresql.JSONB(astext_type=sa.Text()), 'postgresql'), nullable=False),
    sa.Column('status', sa.String(length=32), nullable=False),
    sa.Column('checkpoint', sa.JSON().with_variant(postgresql.JSONB(astext_type=sa.Text()), 'postgresql'), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
    sa.CheckConstraint("access_type IN ('read','write')", name='ck_execution_step_access'),
    sa.CheckConstraint("risk IN ('low','medium','high')", name='ck_execution_step_risk'),
    sa.CheckConstraint("status IN ('pending','running','awaiting_approval','succeeded','failed','cancelled','unknown')", name='ck_execution_step_status'),
    sa.CheckConstraint('position >= 0', name='ck_execution_step_position'),
    sa.ForeignKeyConstraint(['permission'], ['permissions.key'], ),
    sa.ForeignKeyConstraint(['workspace_id', 'execution_id'], ['executions.workspace_id', 'executions.id'], name='fk_execution_step_execution', ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('workspace_id', 'execution_id', 'position', name='uq_execution_step_position')
    )
    op.create_index(op.f('ix_execution_steps_execution_id'), 'execution_steps', ['execution_id'], unique=False)
    op.create_index(op.f('ix_execution_steps_workspace_id'), 'execution_steps', ['workspace_id'], unique=False)
    # ### end Alembic commands ###

def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_execution_steps_workspace_id'), table_name='execution_steps')
    op.drop_index(op.f('ix_execution_steps_execution_id'), table_name='execution_steps')
    op.drop_table('execution_steps')
    op.drop_index(op.f('ix_executions_workspace_id'), table_name='executions')
    op.drop_index(op.f('ix_executions_requested_by_user_id'), table_name='executions')
    op.drop_index('ix_execution_workspace_status_created', table_name='executions')
    op.drop_table('executions')
    # ### end Alembic commands ###
