from importlib import import_module
from json import load
from os.path import basename, dirname, join
from sys import argv, exit

from pyramid.paster import get_appsettings, setup_logging
from pyramid.scripts.common import parse_vars
from transaction import manager

from app.fixtures import __file__ as fixture_base_dir
from app.helpers import TreeHelper
from app.models import __file__ as model_base_dir
from app.models import __name__ as models_qualname
from app.models import get_engine, get_session_factory, get_tm_session
from app.models.__meta__ import Base


def usage(argv):
    cmd = basename(argv[0])
    print('usage: {} <config_uri> [var=value]'.format(cmd))
    print('(example: "{} development.ini"'.format(cmd))
    exit(1)


def main(argv=argv):
    if len(argv) < 2:
        usage(argv)

    config_uri = argv[1]
    setup_logging(config_uri)

    options = parse_vars(argv[2:])
    settings = get_appsettings(config_uri, options=options)

    engine = get_engine(settings)
    Base.metadata.create_all(engine)

    fixture_dir = dirname(fixture_base_dir)

    model_tree = TreeHelper(model_base_dir)
    model_modules = model_tree.modules()

    with manager:
        session_factory = get_session_factory(engine)
        dbsession = get_tm_session(session_factory, manager)

        for module in model_modules:
            package = '{}.{}'.format(models_qualname, module)
            module_ = import_module(package)

            class_name_prefix = module.title()
            class_name_suffix = 'Model'
            class_name = '{}{}'.format(class_name_prefix, class_name_suffix)
            class_obj = getattr(module_, class_name)

            fixture_ext = 'json'
            fixture_name = '{}.{}'.format(module, fixture_ext)
            fixture_path = join(fixture_dir, fixture_name)

            with open(fixture_path) as file_:
                fixtures = load(file_)
                [dbsession.add(class_obj(**f)) for f in fixtures]
