# -*- coding: utf-8 -*-
import logging


def get_or_create(db, model, defaults=None, **kwargs):
    """
    Database models wrapper
    :param db: type sqlalchemy flask instance
    :param model: type Model
    :param defaults: type dict
    :param kwargs: type dict
    :return: instance, boolean
    """
    instance = get_instance(db, model, **kwargs)
    if instance:
        return instance
    else:
        params = {k: v for k, v in kwargs.items()}
        params.update(defaults or {})
        instance = model(**params)
        try:
            db.session.add(instance)
            db.session.commit()
        except Exception as exc:
            logging.exception(exc)
            db.session.rollback()
            instance = db.session.query(model).filter_by(**kwargs).one()
            return instance
        else:
            return instance


def get_instance(db, model, **kwargs):
    instance = db.session.query(model).filter_by(**kwargs).one_or_none()
    return instance


def get_and_delete(db, model, **kwargs):
    instance = get_instance(db, model, **kwargs)
    try:
        db.session.remove(instance)
        db.session.commit()
    except Exception as exc:
        db.session.rollback()
        logging.exception(exc)
        return False
    return True


def create_or_update(db, model, required_args, full_args):
    instance = None
    try:
        instance = get_instance(db, model, **required_args)
        if instance:
            instance.update(**full_args)
        else:
            instance = model(**full_args)
            db.session.add(instance)
        db.session.commit()
    except Exception as exc:
        db.session.rollback()
        logging.exception(exc)
    return instance


