import datetime
import logging
import contextlib

from sqlalchemy.exc import SQLAlchemyError

from .models import Task
from .. import db


class Logger:
    def __init__(self, task_id):
        self.task_id = task_id

    def put(self, mess, level):
        try:
            with db.get_write_session('core') as session:
                session.query(Task).get(self.task_id).log += \
                    '[%(time)s] %(level)s: %(mess)s\n' % (
                        {'time': datetime.datetime.now().strftime("%d/%m/%y %H:%M:%S"),
                         'level': level,
                         'mess': mess})
        except SQLAlchemyError:
            logging.exception('could not add message: "%s" to db log of task id: %s',
                              mess, self.task_id)
            pass

    def info(self, mess):
        self.put(mess, 'INFO')

    def warning(self, mess):
        self.put(mess, 'WARNING')

    def error(self, mess):
        self.put(mess, 'ERROR')


class TaskLogHandler(logging.Handler):
    def __init__(self, task_id):
        logging.Handler.__init__(self, logging.INFO)
        self.formatter = logging.Formatter('[%(asctime)s] %(levelname)s: %(message)s',
                                           '%d/%m/%y %H:%M:%S')
        self.task_id = task_id

    @db.write_session('core')
    def emit(self, record, session):
        session.query(Task).get(self.task_id).log += self.format(record) + '\n'


@contextlib.contextmanager
def task_logger(task_id):
    try:
        handler = TaskLogHandler(task_id)
        logging.getLogger().addHandler(handler)
        yield
    finally:
        logging.getLogger().removeHandler(handler)
