# -*- coding: utf-8 -*-

#   This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
#     Copyright (C) 2019 pwr
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program. If not, see <http://www.gnu.org/licenses/>.

from __future__ import division, print_function, unicode_literals
import os
import inspect
import logging
from logging import Formatter, StreamHandler
from logging.handlers import RotatingFileHandler

from .constants import BASE_DIR as _BASE_DIR

ACCESS_FORMATTER_GEVENT  = Formatter("%(message)s")
ACCESS_FORMATTER_TORNADO = Formatter("[%(asctime)s] %(message)s")

FORMATTER           = Formatter("[%(asctime)s] %(levelname)5s {%(name)s:%(lineno)d} %(message)s")
DEFAULT_LOG_LEVEL   = logging.INFO
DEFAULT_LOG_FILE    = os.path.join(_BASE_DIR, "calibre-web.log")
DEFAULT_ACCESS_LOG  = os.path.join(_BASE_DIR, "access.log")
LOG_TO_STDERR       = '/dev/stderr'
DEFAULT_ACCESS_LEVEL= logging.INFO

logging.addLevelName(logging.WARNING, "WARN")
logging.addLevelName(logging.CRITICAL, "CRIT")


def get(name=None):
    return logging.getLogger(name)


def create():
    parent_frame = inspect.stack(0)[1]
    if hasattr(parent_frame, 'frame'):
        parent_frame = parent_frame.frame
    else:
        parent_frame = parent_frame[0]
    parent_module = inspect.getmodule(parent_frame)
    return get(parent_module.__name__)


def is_debug_enabled():
    return logging.root.level <= logging.DEBUG

def is_info_enabled(logger):
    return logging.getLogger(logger).level <= logging.INFO


def get_level_name(level):
    return logging.getLevelName(level)


def is_valid_logfile(file_path):
    if not file_path:
        return True
    if os.path.isdir(file_path):
        return False
    log_dir = os.path.dirname(file_path)
    return (not log_dir) or os.path.isdir(log_dir)


def setup(log_file, log_level=None, logger=None):
    if logger != "access" and logger != "tornado.access":
        formatter = FORMATTER
        default_file = DEFAULT_LOG_FILE
    else:
        if logger == "tornado.access":
            formatter = ACCESS_FORMATTER_TORNADO
        else:
            formatter = ACCESS_FORMATTER_GEVENT
        default_file = DEFAULT_ACCESS_LOG
    if log_file:
        if not os.path.dirname(log_file):
            log_file = os.path.join(_BASE_DIR, log_file)
        log_file = os.path.abspath(log_file)
    else:
        log_file = LOG_TO_STDERR
        # log_file = default_file

    # print ('%r -- %r' % (log_level, log_file))
    if logger != "access" and logger != "tornado.access":
        r = logging.root
    else:
        r = logging.getLogger(logger)
        r.propagate = False
    r.setLevel(log_level or DEFAULT_LOG_LEVEL)

    previous_handler = r.handlers[0] if r.handlers else None
    # print ('previous %r' % previous_handler)

    if previous_handler:
        # if the log_file has not changed, don't create a new handler
        if getattr(previous_handler, 'baseFilename', None) == log_file:
            return
        r.debug("logging to %s level %s", log_file, r.level)

    if log_file == LOG_TO_STDERR:
        file_handler = StreamHandler()
        file_handler.baseFilename = LOG_TO_STDERR
    else:
        try:
            file_handler = RotatingFileHandler(log_file, maxBytes=50000, backupCount=2)
        except IOError:
            if log_file == default_file:
                raise
            file_handler = RotatingFileHandler(default_file, maxBytes=50000, backupCount=2)
    file_handler.setFormatter(formatter)

    for h in r.handlers:
        r.removeHandler(h)
        h.close()
    r.addHandler(file_handler)
    # print ('new handler %r' % file_handler)


# Enable logging of smtp lib debug output
class StderrLogger(object):
    def __init__(self, name=None):
        self.log = get(name or self.__class__.__name__)
        self.buffer = ''

    def write(self, message):
        try:
            if message == '\n':
                self.log.debug(self.buffer.replace('\n', '\\n'))
                self.buffer = ''
            else:
                self.buffer += message
        except Exception:
            self.log.debug("Logging Error")
