"""
BitBake 'msg' implementation

Message handling infrastructure for bitbake

"""

# Copyright (C) 2006        Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
#

import sys
import copy
import logging
import logging.config
import os
from itertools import groupby
import bb
import bb.event

class BBLogFormatter(logging.Formatter):
    """Formatter which ensures that our 'plain' messages (logging.INFO + 1) are used as is"""

    DEBUG3 = logging.DEBUG - 2
    DEBUG2 = logging.DEBUG - 1
    DEBUG = logging.DEBUG
    VERBOSE = logging.INFO - 1
    NOTE = logging.INFO
    PLAIN = logging.INFO + 1
    VERBNOTE = logging.INFO + 2
    ERROR = logging.ERROR
    ERRORONCE = logging.ERROR - 1
    WARNING = logging.WARNING
    WARNONCE = logging.WARNING - 1
    CRITICAL = logging.CRITICAL

    levelnames = {
        DEBUG3   : 'DEBUG',
        DEBUG2   : 'DEBUG',
        DEBUG   : 'DEBUG',
        VERBOSE: 'NOTE',
        NOTE    : 'NOTE',
        PLAIN  : '',
        VERBNOTE: 'NOTE',
        WARNING : 'WARNING',
        WARNONCE : 'WARNING',
        ERROR   : 'ERROR',
        ERRORONCE   : 'ERROR',
        CRITICAL: 'ERROR',
    }

    color_enabled = False
    BASECOLOR, BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = list(range(29,38))

    COLORS = {
        DEBUG3  : CYAN,
        DEBUG2  : CYAN,
        DEBUG   : CYAN,
        VERBOSE : BASECOLOR,
        NOTE    : BASECOLOR,
        PLAIN   : BASECOLOR,
        VERBNOTE: BASECOLOR,
        WARNING : YELLOW,
        WARNONCE : YELLOW,
        ERROR   : RED,
        ERRORONCE : RED,
        CRITICAL: RED,
    }

    BLD = '\033[1;%dm'
    STD = '\033[%dm'
    RST = '\033[0m'

    def getLevelName(self, levelno):
        try:
            return self.levelnames[levelno]
        except KeyError:
            self.levelnames[levelno] = value = 'Level %d' % levelno
            return value

    def format(self, record):
        record.levelname = self.getLevelName(record.levelno)
        if record.levelno == self.PLAIN:
            msg = record.getMessage()
        else:
            if self.color_enabled:
                record = self.colorize(record)
            msg = logging.Formatter.format(self, record)
        if hasattr(record, 'bb_exc_formatted'):
            msg += '\n' + ''.join(record.bb_exc_formatted)
        elif hasattr(record, 'bb_exc_info'):
            etype, value, tb = record.bb_exc_info
            formatted = bb.exceptions.format_exception(etype, value, tb, limit=5)
            msg += '\n' + ''.join(formatted)
        return msg

    def colorize(self, record):
        color = self.COLORS[record.levelno]
        if self.color_enabled and color is not None:
            record = copy.copy(record)
            record.levelname = "".join([self.BLD % color, record.levelname, self.RST])
            record.msg = "".join([self.STD % color, record.msg, self.RST])
        return record

    def enable_color(self):
        self.color_enabled = True

    def __repr__(self):
        return "%s fmt='%s' color=%s" % (self.__class__.__name__, self._fmt, "True" if self.color_enabled else "False")

class BBLogFilter(object):
    def __init__(self, handler, level, debug_domains):
        self.stdlevel = level
        self.debug_domains = debug_domains
        loglevel = level
        for domain in debug_domains:
            if debug_domains[domain] < loglevel:
                loglevel = debug_domains[domain]
        handler.setLevel(loglevel)
        handler.addFilter(self)

    def filter(self, record):
        if record.levelno >= self.stdlevel:
            return True
        if record.name in self.debug_domains and record.levelno >= self.debug_domains[record.name]:
            return True
        return False

class LogFilterShowOnce(logging.Filter):
    def __init__(self):
        self.seen_warnings = set()
        self.seen_errors = set()

    def filter(self, record):
        msg = record.msg
        if record.levelno == bb.msg.BBLogFormatter.WARNONCE:
            if record.msg in self.seen_warnings:
                return False
            self.seen_warnings.add(record.msg)
        if record.levelno == bb.msg.BBLogFormatter.ERRORONCE:
            if record.msg in self.seen_errors:
                return False
            self.seen_errors.add(record.msg)
        return True

class LogFilterGEQLevel(logging.Filter):
    def __init__(self, level):
        self.strlevel = str(level)
        self.level = stringToLevel(level)

    def __repr__(self):
        return "%s level >= %s (%d)" % (self.__class__.__name__, self.strlevel, self.level)

    def filter(self, record):
        return (record.levelno >= self.level)

class LogFilterLTLevel(logging.Filter):
    def __init__(self, level):
        self.strlevel = str(level)
        self.level = stringToLevel(level)

    def __repr__(self):
        return "%s level < %s (%d)" % (self.__class__.__name__, self.strlevel, self.level)

    def filter(self, record):
        return (record.levelno < self.level)

# Message control functions
#

loggerDefaultLogLevel = BBLogFormatter.NOTE
loggerDefaultDomains = {}

def init_msgconfig(verbose, debug, debug_domains=None):
    """
    Set default verbosity and debug levels config the logger
    """
    if debug:
        bb.msg.loggerDefaultLogLevel = BBLogFormatter.DEBUG - debug + 1
    elif verbose:
        bb.msg.loggerDefaultLogLevel = BBLogFormatter.VERBOSE
    else:
        bb.msg.loggerDefaultLogLevel = BBLogFormatter.NOTE

    bb.msg.loggerDefaultDomains = {}
    if debug_domains:
        for (domainarg, iterator) in groupby(debug_domains):
            dlevel = len(tuple(iterator))
            bb.msg.loggerDefaultDomains["BitBake.%s" % domainarg] = logging.DEBUG - dlevel + 1

def constructLogOptions():
    return loggerDefaultLogLevel, loggerDefaultDomains

def addDefaultlogFilter(handler, cls = BBLogFilter, forcelevel=None):
    level, debug_domains = constructLogOptions()

    if forcelevel is not None:
        level = forcelevel

    cls(handler, level, debug_domains)

def stringToLevel(level):
    try:
        return int(level)
    except ValueError:
        pass

    try:
        return getattr(logging, level)
    except AttributeError:
        pass

    return getattr(BBLogFormatter, level)

#
# Message handling functions
#

def fatal(msgdomain, msg):
    if msgdomain:
        logger = logging.getLogger("BitBake.%s" % msgdomain)
    else:
        logger = logging.getLogger("BitBake")
    logger.critical(msg)
    sys.exit(1)

def logger_create(name, output=sys.stderr, level=logging.INFO, preserve_handlers=False, color='auto'):
    """Standalone logger creation function"""
    logger = logging.getLogger(name)
    console = logging.StreamHandler(output)
    console.addFilter(bb.msg.LogFilterShowOnce())
    format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
    if color == 'always' or (color == 'auto' and output.isatty()):
        format.enable_color()
    console.setFormatter(format)
    if preserve_handlers:
        logger.addHandler(console)
    else:
        logger.handlers = [console]
    logger.setLevel(level)
    return logger

def has_console_handler(logger):
    for handler in logger.handlers:
        if isinstance(handler, logging.StreamHandler):
            if handler.stream in [sys.stderr, sys.stdout]:
                return True
    return False

def mergeLoggingConfig(logconfig, userconfig):
    logconfig = copy.deepcopy(logconfig)
    userconfig = copy.deepcopy(userconfig)

    # Merge config with the default config
    if userconfig.get('version') != logconfig['version']:
        raise BaseException("Bad user configuration version. Expected %r, got %r" % (logconfig['version'], userconfig.get('version')))

    # Set some defaults to make merging easier
    userconfig.setdefault("loggers", {})

    # If a handler, formatter, or filter is defined in the user
    # config, it will replace an existing one in the default config
    for k in ("handlers", "formatters", "filters"):
        logconfig.setdefault(k, {}).update(userconfig.get(k, {}))

    seen_loggers = set()
    for name, l in logconfig["loggers"].items():
        # If the merge option is set, merge the handlers and
        # filters. Otherwise, if it is False, this logger won't get
        # add to the set of seen loggers and will replace the
        # existing one
        if l.get('bitbake_merge', True):
            ulogger = userconfig["loggers"].setdefault(name, {})
            ulogger.setdefault("handlers", [])
            ulogger.setdefault("filters", [])

            # Merge lists
            l.setdefault("handlers", []).extend(ulogger["handlers"])
            l.setdefault("filters", []).extend(ulogger["filters"])

            # Replace other properties if present
            if "level" in ulogger:
                l["level"] = ulogger["level"]

            if "propagate" in ulogger:
                l["propagate"] = ulogger["propagate"]

            seen_loggers.add(name)

    # Add all loggers present in the user config, but not any that
    # have already been processed
    for name in set(userconfig["loggers"].keys()) - seen_loggers:
        logconfig["loggers"][name] = userconfig["loggers"][name]

    return logconfig

def setLoggingConfig(defaultconfig, userconfigfile=None):
    logconfig = copy.deepcopy(defaultconfig)

    if userconfigfile:
        with open(os.path.normpath(userconfigfile), 'r') as f:
            if userconfigfile.endswith('.yml') or userconfigfile.endswith('.yaml'):
                import yaml
                userconfig = yaml.safe_load(f)
            elif userconfigfile.endswith('.json') or userconfigfile.endswith('.cfg'):
                import json
                userconfig = json.load(f)
            else:
                raise BaseException("Unrecognized file format: %s" % userconfigfile)

            if userconfig.get('bitbake_merge', True):
                logconfig = mergeLoggingConfig(logconfig, userconfig)
            else:
                # Replace the entire default config
                logconfig = userconfig

    # Convert all level parameters to integers in case users want to use the
    # bitbake defined level names
    for name, h in logconfig["handlers"].items():
        if "level" in h:
            h["level"] = bb.msg.stringToLevel(h["level"])

        # Every handler needs its own instance of the once filter.
        once_filter_name = name + ".showonceFilter"
        logconfig.setdefault("filters", {})[once_filter_name] = {
            "()": "bb.msg.LogFilterShowOnce",
        }
        h.setdefault("filters", []).append(once_filter_name)

    for l in logconfig["loggers"].values():
        if "level" in l:
            l["level"] = bb.msg.stringToLevel(l["level"])

    conf = logging.config.dictConfigClass(logconfig)
    conf.configure()

    # The user may have specified logging domains they want at a higher debug
    # level than the standard.
    for name, l in logconfig["loggers"].items():
        if not name.startswith("BitBake."):
            continue

        if not "level" in l:
            continue

        curlevel = bb.msg.loggerDefaultDomains.get(name)
        # Note: level parameter should already be a int because of conversion
        # above
        newlevel = int(l["level"])
        if curlevel is None or newlevel < curlevel:
            bb.msg.loggerDefaultDomains[name] = newlevel

        # TODO: I don't think that setting the global log level should be necessary
        #if newlevel < bb.msg.loggerDefaultLogLevel:
        #    bb.msg.loggerDefaultLogLevel = newlevel

    return conf
