import os
from collections.abc import Sequence
from pathlib import Path

from alembic import op


def get_revision() -> str:
    return Path(__file__).name.split("-")[0]


def get_down_revision() -> str | None:
    versions_path = Path(__file__).parent
    migration_files = sorted([f.name for f in versions_path.iterdir() if f.is_file()])
    for i, file in enumerate(migration_files):
        if file == Path(__file__).name:
            return None if i == 0 else migration_files[i - 1].split("-")[0]
    return None


# revision identifiers, used by Alembic.
revision: str = get_revision()
down_revision: str | None = get_down_revision()
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None

tables = [
    # "tenants", authorizerにてapplication_client_idで検索するため除外
    "quota_allocations",
    # "clients", テナントに紐づかないため除外
    # "client_api_keys", テナントに紐づかないため除外
    # "client_tenants", authorizerにてclient_tenant_nameで検索するため除外
    "usage_events",
    "quota_usages",
    # "prices", テナントに紐づかないため除外
]

username = os.getenv("POSTGRES_APP_USER", "app")
password = os.getenv("POSTGRES_APP_PASSWORD", "app")


def upgrade() -> None:
    op.execute(f"CREATE ROLE {username} WITH LOGIN PASSWORD '{password}'")
    op.execute(f"GRANT ALL ON ALL TABLES IN SCHEMA public TO {username}")
    op.execute(f"GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO {username}")
    op.execute(f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO {username}")
    op.execute(f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO {username}")

    for table in tables:
        op.execute(f"ALTER TABLE {table} ENABLE ROW LEVEL SECURITY")
        tenant_id_col = "id" if table == "tenants" else "tenant_id"
        op.execute(
            (
                f"CREATE POLICY tenant_isolation_policy ON {table} "
                f"USING ({tenant_id_col} = current_setting('app.tenant_id')::UUID)"
            ),
        )


def downgrade() -> None:
    for table in tables:
        op.execute(f"DROP POLICY tenant_isolation_policy ON {table}")
        op.execute(f"ALTER TABLE {table} DISABLE ROW LEVEL SECURITY")
    op.execute(f"ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON SEQUENCES FROM {username}")
    op.execute(f"ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM {username}")
    op.execute(f"REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM {username}")
    op.execute(f"REVOKE ALL ON ALL TABLES IN SCHEMA public FROM {username}")
    op.execute(f"DROP ROLE {username}")
