import os
import sys
from alembic.config import CommandLine, Config
from alembic.script import ScriptDirectory

from library.python import resource
from intranet.trip.src.config import settings


def extract_resources(prefix):
    for res, data in resource.iteritems(prefix='resfs/file/{}'.format(prefix), strip_prefix=True):
        path = os.path.join('alembic', res)
        if not os.path.exists(path):
            parent = os.path.normpath(os.path.join(path, os.pardir))
            if not os.path.exists(parent):
                os.makedirs(parent)
            with open(path, 'wb') as f:
                f.write(data)


def generate_sequential_revision_number(config: Config) -> str:
    """
    Generate revision number as sequential hexadecimal string of length 12 (default rev number
    length in alembic).

    :param config: Alembic config.
    """
    new_migration_number = 1
    script = ScriptDirectory.from_config(config)

    heads = script.get_heads()
    if heads:
        new_migration_number = int(script.get_heads()[0]) + 1

    return f'{new_migration_number:04d}'


def main():
    extract_resources('intranet/trip/alembic/')

    alembic = CommandLine()
    options = alembic.parser.parse_args()
    if not hasattr(options, "cmd"):
        # see http://bugs.python.org/issue9253, argparse
        # behavior changed incompatibly in py3.3
        alembic.parser.error("too few arguments")

    config = Config(
        file_=options.config,
        ini_section=options.name,
        cmd_opts=options,
    )
    config.set_main_option('sqlalchemy.url', settings.database_url)

    if options.cmd[0].__name__ == 'revision' and options.rev_id is None:
        options.rev_id = generate_sequential_revision_number(config)

    sys.exit(alembic.run_cmd(config, options))


if __name__ == '__main__':
    main()
