from pathlib import Path

import typer
from alembic import command as alembic_command
from alembic.util.exc import AutogenerateDiffsDetected, CommandError

from .. import defaults as _defaults
from .. import env as _env
from ..alembic_utils import HitfactorpyAlembicConfig
from ..session import get_sqlalchemy_url

cli = typer.Typer()


@cli.command()
def check(
    sqlalchemy_url: str = typer.Option(get_sqlalchemy_url(), envvar=_env.HITFACTORPY_DB_SQLALCHEMY_URL),
    alembic_dir: Path = typer.Option(_defaults.HITFACTORPY_DB_ALEMBIC_DIR, envvar=_env.HITFACTORPY_DB_ALEMBIC_DIR),
):
    """alembic check"""
    alembic_cfg = HitfactorpyAlembicConfig(script_location=alembic_dir, sqlalchemy_url=sqlalchemy_url)

    try:
        alembic_command.check(alembic_cfg)
    except (AutogenerateDiffsDetected, CommandError) as e:
        typer.echo(e)
        raise typer.Exit(1)
    typer.echo("OK: DB and code are in sync")


@cli.command()
def upgrade(
    revision: str = "head",
    sqlalchemy_url: str = typer.Option(get_sqlalchemy_url(), envvar=_env.HITFACTORPY_DB_SQLALCHEMY_URL),
    alembic_dir: Path = typer.Option(_defaults.HITFACTORPY_DB_ALEMBIC_DIR, envvar=_env.HITFACTORPY_DB_ALEMBIC_DIR),
):
    """alembic upgrade <revision>"""
    alembic_cfg = HitfactorpyAlembicConfig(script_location=alembic_dir, sqlalchemy_url=sqlalchemy_url)

    try:
        alembic_command.upgrade(alembic_cfg, revision)
    except (AutogenerateDiffsDetected, CommandError) as e:
        typer.echo(e)
        raise typer.Exit(1)
    typer.echo("OK: migration upgrade applied")


@cli.command()
def downgrade(
    revision: str = "-1",
    sqlalchemy_url: str = typer.Option(get_sqlalchemy_url(), envvar=_env.HITFACTORPY_DB_SQLALCHEMY_URL),
    alembic_dir: Path = typer.Option(_defaults.HITFACTORPY_DB_ALEMBIC_DIR, envvar=_env.HITFACTORPY_DB_ALEMBIC_DIR),
):
    """alembic downgrade <revision>"""
    alembic_cfg = HitfactorpyAlembicConfig(script_location=alembic_dir, sqlalchemy_url=sqlalchemy_url)

    typer.confirm("Are you sure you want to downgrade?", abort=True)

    try:
        alembic_command.downgrade(alembic_cfg, revision)
    except (AutogenerateDiffsDetected, CommandError) as e:
        typer.echo(e)
        raise typer.Exit(1)

    typer.echo("OK: migration downgrade applied")


if __name__ == "__main__":
    cli()
