"""Preflight Alembic state before a production release."""

from __future__ import annotations

import argparse
import os
from dataclasses import dataclass
from pathlib import Path

from sqlalchemy import create_engine, text

REPO_ROOT = Path(__file__).resolve().parents[1]


@dataclass(frozen=True)
class AlembicPreflightResult:
    has_alembic_version: bool
    business_table_count: int
    current_revision: str | None
    head_revision: str

    @property
    def action(self) -> str:
        if self.has_alembic_version:
            if self.current_revision == self.head_revision:
                return "upgrade_head_noop_or_verify"
            return "upgrade_head"
        if self.business_table_count > 0:
            return "stamp_head_then_upgrade_head"
        return "upgrade_head_empty_database"


def get_head_revision() -> str:
    from alembic.config import Config
    from alembic.script import ScriptDirectory

    config = Config(str(REPO_ROOT / "alembic.ini"))
    config.set_main_option("script_location", str(REPO_ROOT / "alembic"))
    script = ScriptDirectory.from_config(config)
    head = script.get_current_head()
    if not head:
        raise RuntimeError("Alembic head revision not found")
    return head


def inspect_database(database_url: str, head_revision: str) -> AlembicPreflightResult:
    engine = create_engine(database_url)
    with engine.begin() as connection:
        has_alembic_version = (
            connection.execute(
                text("SELECT to_regclass(:table_name)"), {"table_name": "public.alembic_version"}
            ).scalar()
            is not None
        )
        business_table_count = connection.execute(
            text("SELECT COUNT(*) FROM pg_tables " "WHERE schemaname = :schema_name AND tablename != :version_table"),
            {"schema_name": "public", "version_table": "alembic_version"},
        ).scalar_one()
        current_revision = None
        if has_alembic_version:
            current_revision = connection.execute(text("SELECT version_num FROM alembic_version LIMIT 1")).scalar()

    return AlembicPreflightResult(
        has_alembic_version=has_alembic_version,
        business_table_count=int(business_table_count),
        current_revision=current_revision,
        head_revision=head_revision,
    )


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--database-url", default=os.getenv("DATABASE_URL"), help="Defaults to DATABASE_URL.")
    args = parser.parse_args()
    if not args.database_url:
        raise SystemExit("DATABASE_URL is required")

    result = inspect_database(args.database_url, get_head_revision())
    print(f"has_alembic_version={str(result.has_alembic_version).lower()}")
    print(f"business_table_count={result.business_table_count}")
    print(f"current_revision={result.current_revision or '<none>'}")
    print(f"head_revision={result.head_revision}")
    print(f"recommended_action={result.action}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
