"""phase 2 runtime permissions

Revision ID: 6b0d8a1c4f2e
Revises: 7e76a1a0dd21
"""

from collections.abc import Sequence

import sqlalchemy as sa
from alembic import op

revision: str = "6b0d8a1c4f2e"
down_revision: str | Sequence[str] | None = "7e76a1a0dd21"
branch_labels = None
depends_on = None

RUNTIME_PERMISSIONS = {
    "system.status.read": "Read explicit service configuration and availability state",
    "workspace.profile.read": "Read the authorized workspace profile",
    "executions.create": "Create AI executions",
    "executions.read": "Read AI execution state",
    "executions.run": "Run authorized AI execution steps",
    "executions.cancel": "Cancel AI executions",
}

ROLE_RUNTIME_PERMISSIONS = {
    "Owner": set(RUNTIME_PERMISSIONS),
    "Administrator": set(RUNTIME_PERMISSIONS),
    "Assistant Manager": set(RUNTIME_PERMISSIONS),
    "Human Assistant": {
        "system.status.read",
        "workspace.profile.read",
        "executions.create",
        "executions.read",
        "executions.run",
    },
    "Viewer": {"system.status.read", "workspace.profile.read", "executions.read"},
    "Developer": set(RUNTIME_PERMISSIONS),
}


def upgrade() -> None:
    permissions = sa.table(
        "permissions",
        sa.column("key", sa.String),
        sa.column("description", sa.String),
    )
    roles = sa.table(
        "roles",
        sa.column("id", sa.Uuid),
        sa.column("workspace_id", sa.Uuid),
        sa.column("name", sa.String),
        sa.column("is_system", sa.Boolean),
    )
    role_permissions = sa.table(
        "role_permissions",
        sa.column("workspace_id", sa.Uuid),
        sa.column("role_id", sa.Uuid),
        sa.column("permission_key", sa.String),
    )
    op.bulk_insert(
        permissions,
        [{"key": key, "description": description}
         for key, description in RUNTIME_PERMISSIONS.items()],
    )
    connection = op.get_bind()
    for role_name, permission_keys in ROLE_RUNTIME_PERMISSIONS.items():
        for permission_key in permission_keys:
            connection.execute(
                role_permissions.insert().from_select(
                    ["workspace_id", "role_id", "permission_key"],
                    sa.select(
                        roles.c.workspace_id,
                        roles.c.id,
                        sa.literal(permission_key),
                    ).where(
                        roles.c.name == role_name,
                        roles.c.is_system.is_(True),
                    ),
                )
            )


def downgrade() -> None:
    role_permissions = sa.table(
        "role_permissions",
        sa.column("permission_key", sa.String),
    )
    permissions = sa.table("permissions", sa.column("key", sa.String))
    keys = list(RUNTIME_PERMISSIONS)
    connection = op.get_bind()
    connection.execute(role_permissions.delete().where(role_permissions.c.permission_key.in_(keys)))
    connection.execute(permissions.delete().where(permissions.c.key.in_(keys)))
