from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker


_Session = None


def _build_url(opts):
    if type(opts) is not dict:
        opts = opts.__dict__

    if 'db' not in opts:
        raise RuntimeError('Missing database name.')

    if (opts['db'].endswith('.db') or opts['db'].endswith('.sqlite')
        or opts['db'].endswith('.sqlite3')):
        return f'sqlite:///' + opts['db']
    else:
        return f'postgresql+psycopg2://%s:%@%s/%s' % (opts['user'],
                                                      opts['password'],
                                                      opts['host'],
                                                      opts['db'])


def session(opts=None, migrate=False, reinit=False):
    global _Session

    if reinit:
        _Session = None

    if _Session is None:
        url = _build_url(opts)
        engine = create_engine(url)
        _Session = sessionmaker(bind=engine)

    if migrate:
        from .models import Base
        Base.metadata.create_all(bind=engine)

    return _Session()
