# #region check_migration_chain [C:3] [TYPE Module] [SEMANTICS alembic,migration,validation,ci]
# @BRIEF Validates Alembic migration chain integrity — checks for multiple heads,
#   broken chains, and missing down_revision references.
# @RATIONALE Merge migrations (e.g., f0e9d8c7b6a5) are fragile — a new migration
#   with wrong down_revision can create multiple heads and break `alembic upgrade head`.
#   This script catches the issue before deployment.
# @REJECTED Relying on `alembic upgrade head` to fail at deploy time was rejected —
#   it's better to catch migration chain issues in CI or pre-commit.

import sys
from pathlib import Path

# Ensure backend/src is importable
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))


# #region check_migration_heads [C:2] [TYPE Function]
# @BRIEF Checks that there is exactly one migration head.
# @POST Prints error and exits 1 if multiple heads found.
def check_migration_heads() -> None:
    from alembic.config import Config as AlembicConfig
    from alembic.script import ScriptDirectory

    alembic_cfg = AlembicConfig("alembic.ini")
    alembic_cfg.set_main_option("script_location", "alembic")

    script_dir = ScriptDirectory.from_config(alembic_cfg)
    heads = list(script_dir.get_heads())

    if len(heads) == 0:
        print("[migration-check] ERROR: No migration heads found — chain is empty")
        sys.exit(1)

    if len(heads) > 1:
        print(f"[migration-check] ERROR: Multiple migration heads detected ({len(heads)}):")
        for h in heads:
            rev = script_dir.get_revision(h)
            print(f"  - {h}: {rev.doc}")
        print("[migration-check] Fix: ensure new migrations reference the correct parent")
        sys.exit(1)

    print(f"[migration-check] OK: Single migration head — {heads[0]}")


# #endregion check_migration_heads

# #region check_migration_chain_integrity [C:2] [TYPE Function]
# @BRIEF Walks the migration chain from head to root, checking all down_revision links exist.
# @POST Prints error and exits 1 if a broken link is found.
def check_migration_chain_integrity() -> None:
    from alembic.config import Config as AlembicConfig
    from alembic.script import ScriptDirectory

    alembic_cfg = AlembicConfig("alembic.ini")
    alembic_cfg.set_main_option("script_location", "alembic")

    script_dir = ScriptDirectory.from_config(alembic_cfg)
    heads = list(script_dir.get_heads())

    if not heads:
        return  # already checked above

    visited = set()
    current_revs = heads

    while current_revs:
        next_revs = []
        for rev_id in current_revs:
            if rev_id in visited:
                continue
            visited.add(rev_id)
            rev = script_dir.get_revision(rev_id)

            down = rev.down_revision
            if down is None:
                continue  # root migration

            if isinstance(down, str):
                try:
                    script_dir.get_revision(down)
                except Exception:
                    print(f"[migration-check] ERROR: Broken link — {rev_id} -> {down} (not found)")
                    sys.exit(1)
                next_revs.append(down)
            elif isinstance(down, tuple):
                # Merge migration — check all parents exist
                for parent in down:
                    try:
                        script_dir.get_revision(parent)
                    except Exception:
                        print(f"[migration-check] ERROR: Broken merge link — {rev_id} -> {parent} (not found)")
                        sys.exit(1)
                    next_revs.append(parent)

        current_revs = next_revs

    print(f"[migration-check] OK: Chain integrity verified — {len(visited)} migrations traversed")


# #endregion check_migration_chain_integrity

# #region check_migration_main [C:2] [TYPE Function]
# @BRIEF Entry point — runs all migration chain checks.
def main() -> None:
    print("[migration-check] === Alembic Migration Chain Validation ===")
    check_migration_heads()
    check_migration_chain_integrity()
    print("[migration-check] === All checks passed ===")


# #endregion check_migration_main

if __name__ == "__main__":
    main()
