"""
BitBake 'Event' implementation

Classes and functions for manipulating 'events' in the
BitBake build tools.
"""

# Copyright (C) 2003, 2004  Chris Larson
#
# SPDX-License-Identifier: GPL-2.0-only
#

import ast
import atexit
import collections
import logging
import pickle
import sys
import threading
import traceback

import bb.exceptions
import bb.utils

# This is the pid for which we should generate the event. This is set when
# the runqueue forks off.
worker_pid = 0
worker_fire = None

logger = logging.getLogger('BitBake.Event')

class Event(object):
    """Base class for events"""

    def __init__(self):
        self.pid = worker_pid


class HeartbeatEvent(Event):
    """Triggered at regular time intervals of 10 seconds. Other events can fire much more often
       (runQueueTaskStarted when there are many short tasks) or not at all for long periods
       of time (again runQueueTaskStarted, when there is just one long-running task), so this
       event is more suitable for doing some task-independent work occassionally."""
    def __init__(self, time):
        Event.__init__(self)
        self.time = time

Registered        = 10
AlreadyRegistered = 14

def get_class_handlers():
    return _handlers

def set_class_handlers(h):
    global _handlers
    _handlers = h

def clean_class_handlers():
    return collections.OrderedDict()

# Internal
_handlers = clean_class_handlers()
_ui_handlers = {}
_ui_logfilters = {}
_ui_handler_seq = 0
_event_handler_map = {}
_catchall_handlers = {}
_eventfilter = None
_uiready = False
_thread_lock = threading.Lock()
_thread_lock_enabled = False

if hasattr(__builtins__, '__setitem__'):
    builtins = __builtins__
else:
    builtins = __builtins__.__dict__

def enable_threadlock():
    global _thread_lock_enabled
    _thread_lock_enabled = True

def disable_threadlock():
    global _thread_lock_enabled
    _thread_lock_enabled = False

def execute_handler(name, handler, event, d):
    event.data = d
    addedd = False
    if 'd' not in builtins:
        builtins['d'] = d
        addedd = True
    try:
        ret = handler(event)
    except (bb.parse.SkipRecipe, bb.BBHandledException):
        raise
    except Exception:
        etype, value, tb = sys.exc_info()
        logger.error("Execution of event handler '%s' failed" % name,
                        exc_info=(etype, value, tb.tb_next))
        raise
    except SystemExit as exc:
        if exc.code != 0:
            logger.error("Execution of event handler '%s' failed" % name)
        raise
    finally:
        del event.data
        if addedd:
            del builtins['d']

def fire_class_handlers(event, d):
    if isinstance(event, logging.LogRecord):
        return

    eid = str(event.__class__)[8:-2]
    evt_hmap = _event_handler_map.get(eid, {})
    for name, handler in list(_handlers.items()):
        if name in _catchall_handlers or name in evt_hmap:
            if _eventfilter:
                if not _eventfilter(name, handler, event, d):
                    continue
            execute_handler(name, handler, event, d)

ui_queue = []
@atexit.register
def print_ui_queue():
    global ui_queue
    """If we're exiting before a UI has been spawned, display any queued
    LogRecords to the console."""
    logger = logging.getLogger("BitBake")
    if not _uiready:
        from bb.msg import BBLogFormatter
        # Flush any existing buffered content
        sys.stdout.flush()
        sys.stderr.flush()
        stdout = logging.StreamHandler(sys.stdout)
        stderr = logging.StreamHandler(sys.stderr)
        formatter = BBLogFormatter("%(levelname)s: %(message)s")
        stdout.setFormatter(formatter)
        stderr.setFormatter(formatter)

        # First check to see if we have any proper messages
        msgprint = False
        msgerrs = False

        # Should we print to stderr?
        for event in ui_queue[:]:
            if isinstance(event, logging.LogRecord) and event.levelno >= logging.WARNING:
                msgerrs = True
                break

        if msgerrs:
            logger.addHandler(stderr)
        else:
            logger.addHandler(stdout)

        for event in ui_queue[:]:
            if isinstance(event, logging.LogRecord):
                if event.levelno > logging.DEBUG:
                    logger.handle(event)
                    msgprint = True

        # Nope, so just print all of the messages we have (including debug messages)
        if not msgprint:
            for event in ui_queue[:]:
                if isinstance(event, logging.LogRecord):
                    logger.handle(event)
        if msgerrs:
            logger.removeHandler(stderr)
        else:
            logger.removeHandler(stdout)
        ui_queue = []

def fire_ui_handlers(event, d):
    global _thread_lock
    global _thread_lock_enabled

    if not _uiready:
        # No UI handlers registered yet, queue up the messages
        ui_queue.append(event)
        return

    if _thread_lock_enabled:
        _thread_lock.acquire()

    errors = []
    for h in _ui_handlers:
        #print "Sending event %s" % event
        try:
             if not _ui_logfilters[h].filter(event):
                 continue
             # We use pickle here since it better handles object instances
             # which xmlrpc's marshaller does not. Events *must* be serializable
             # by pickle.
             if hasattr(_ui_handlers[h].event, "sendpickle"):
                _ui_handlers[h].event.sendpickle((pickle.dumps(event)))
             else:
                _ui_handlers[h].event.send(event)
        except:
            errors.append(h)
    for h in errors:
        del _ui_handlers[h]

    if _thread_lock_enabled:
        _thread_lock.release()

def fire(event, d):
    """Fire off an Event"""

    # We can fire class handlers in the worker process context and this is
    # desired so they get the task based datastore.
    # UI handlers need to be fired in the server context so we defer this. They
    # don't have a datastore so the datastore context isn't a problem.

    fire_class_handlers(event, d)
    if worker_fire:
        worker_fire(event, d)
    else:
        # If messages have been queued up, clear the queue
        global _uiready, ui_queue
        if _uiready and ui_queue:
            for queue_event in ui_queue:
                fire_ui_handlers(queue_event, d)
            ui_queue = []
        fire_ui_handlers(event, d)

def fire_from_worker(event, d):
    fire_ui_handlers(event, d)

noop = lambda _: None
def register(name, handler, mask=None, filename=None, lineno=None):
    """Register an Event handler"""

    # already registered
    if name in _handlers:
        return AlreadyRegistered

    if handler is not None:
        # handle string containing python code
        if isinstance(handler, str):
            tmp = "def %s(e):\n%s" % (name, handler)
            try:
                code = bb.methodpool.compile_cache(tmp)
                if not code:
                    if filename is None:
                        filename = "%s(e)" % name
                    code = compile(tmp, filename, "exec", ast.PyCF_ONLY_AST)
                    if lineno is not None:
                        ast.increment_lineno(code, lineno-1)
                    code = compile(code, filename, "exec")
                    bb.methodpool.compile_cache_add(tmp, code)
            except SyntaxError:
                logger.error("Unable to register event handler '%s':\n%s", name,
                             ''.join(traceback.format_exc(limit=0)))
                _handlers[name] = noop
                return
            env = {}
            bb.utils.better_exec(code, env)
            func = bb.utils.better_eval(name, env)
            _handlers[name] = func
        else:
            _handlers[name] = handler

        if not mask or '*' in mask:
            _catchall_handlers[name] = True
        else:
            for m in mask:
                if _event_handler_map.get(m, None) is None:
                    _event_handler_map[m] = {}
                _event_handler_map[m][name] = True

        return Registered

def remove(name, handler):
    """Remove an Event handler"""
    _handlers.pop(name)
    if name in _catchall_handlers:
        _catchall_handlers.pop(name)
    for event in _event_handler_map.keys():
        if name in _event_handler_map[event]:
            _event_handler_map[event].pop(name)

def get_handlers():
    return _handlers

def set_handlers(handlers):
    global _handlers
    _handlers = handlers

def set_eventfilter(func):
    global _eventfilter
    _eventfilter = func

def register_UIHhandler(handler, mainui=False):
    bb.event._ui_handler_seq = bb.event._ui_handler_seq + 1
    _ui_handlers[_ui_handler_seq] = handler
    level, debug_domains = bb.msg.constructLogOptions()
    _ui_logfilters[_ui_handler_seq] = UIEventFilter(level, debug_domains)
    if mainui:
        global _uiready
        _uiready = _ui_handler_seq
    return _ui_handler_seq

def unregister_UIHhandler(handlerNum, mainui=False):
    if mainui:
        global _uiready
        _uiready = False
    if handlerNum in _ui_handlers:
        del _ui_handlers[handlerNum]
    return

def get_uihandler():
    if _uiready is False:
        return None
    return _uiready

# Class to allow filtering of events and specific filtering of LogRecords *before* we put them over the IPC
class UIEventFilter(object):
    def __init__(self, level, debug_domains):
        self.update(None, level, debug_domains)

    def update(self, eventmask, level, debug_domains):
        self.eventmask = eventmask
        self.stdlevel = level
        self.debug_domains = debug_domains

    def filter(self, event):
        if isinstance(event, logging.LogRecord):
            if event.levelno >= self.stdlevel:
                return True
            if event.name in self.debug_domains and event.levelno >= self.debug_domains[event.name]:
                return True
            return False
        eid = str(event.__class__)[8:-2]
        if self.eventmask and eid not in self.eventmask:
            return False
        return True

def set_UIHmask(handlerNum, level, debug_domains, mask):
    if not handlerNum in _ui_handlers:
        return False
    if '*' in mask:
        _ui_logfilters[handlerNum].update(None, level, debug_domains)
    else:
        _ui_logfilters[handlerNum].update(mask, level, debug_domains)
    return True

def getName(e):
    """Returns the name of a class or class instance"""
    if getattr(e, "__name__", None) is None:
        return e.__class__.__name__
    else:
        return e.__name__

class OperationStarted(Event):
    """An operation has begun"""
    def __init__(self, msg = "Operation Started"):
        Event.__init__(self)
        self.msg = msg

class OperationCompleted(Event):
    """An operation has completed"""
    def __init__(self, total, msg = "Operation Completed"):
        Event.__init__(self)
        self.total = total
        self.msg = msg

class OperationProgress(Event):
    """An operation is in progress"""
    def __init__(self, current, total, msg = "Operation in Progress"):
        Event.__init__(self)
        self.current = current
        self.total = total
        self.msg = msg + ": %s/%s" % (current, total);

class ConfigParsed(Event):
    """Configuration Parsing Complete"""

class MultiConfigParsed(Event):
    """Multi-Config Parsing Complete"""
    def __init__(self, mcdata):
        self.mcdata = mcdata
        Event.__init__(self)

class RecipeEvent(Event):
    def __init__(self, fn):
        self.fn = fn
        Event.__init__(self)

class RecipePreFinalise(RecipeEvent):
    """ Recipe Parsing Complete but not yet finalised"""

class RecipePostKeyExpansion(RecipeEvent):
    """ Recipe Parsing Complete but not yet finalised"""


class RecipeTaskPreProcess(RecipeEvent):
    """
    Recipe Tasks about to be finalised
    The list of tasks should be final at this point and handlers
    are only able to change interdependencies
    """
    def __init__(self, fn, tasklist):
        self.fn = fn
        self.tasklist = tasklist
        Event.__init__(self)

class RecipeParsed(RecipeEvent):
    """ Recipe Parsing Complete """

class BuildBase(Event):
    """Base class for bitbake build events"""

    def __init__(self, n, p, failures = 0):
        self._name = n
        self._pkgs = p
        Event.__init__(self)
        self._failures = failures

    def getPkgs(self):
        return self._pkgs

    def setPkgs(self, pkgs):
        self._pkgs = pkgs

    def getName(self):
        return self._name

    def setName(self, name):
        self._name = name

    def getFailures(self):
        """
        Return the number of failed packages
        """
        return self._failures

    pkgs = property(getPkgs, setPkgs, None, "pkgs property")
    name = property(getName, setName, None, "name property")

class BuildInit(BuildBase):
    """buildFile or buildTargets was invoked"""
    def __init__(self, p=[]):
        name = None
        BuildBase.__init__(self, name, p)

class BuildStarted(BuildBase, OperationStarted):
    """Event when builds start"""
    def __init__(self, n, p, failures = 0):
        OperationStarted.__init__(self, "Building Started")
        BuildBase.__init__(self, n, p, failures)

class BuildCompleted(BuildBase, OperationCompleted):
    """Event when builds have completed"""
    def __init__(self, total, n, p, failures=0, interrupted=0):
        if not failures:
            OperationCompleted.__init__(self, total, "Building Succeeded")
        else:
            OperationCompleted.__init__(self, total, "Building Failed")
        self._interrupted = interrupted
        BuildBase.__init__(self, n, p, failures)

class DiskFull(Event):
    """Disk full case build aborted"""
    def __init__(self, dev, type, freespace, mountpoint):
        Event.__init__(self)
        self._dev = dev
        self._type = type
        self._free = freespace
        self._mountpoint = mountpoint

class DiskUsageSample:
    def __init__(self, available_bytes, free_bytes, total_bytes):
        # Number of bytes available to non-root processes.
        self.available_bytes = available_bytes
        # Number of bytes available to root processes.
        self.free_bytes = free_bytes
        # Total capacity of the volume.
        self.total_bytes = total_bytes

class MonitorDiskEvent(Event):
    """If BB_DISKMON_DIRS is set, then this event gets triggered each time disk space is checked.
       Provides information about devices that are getting monitored."""
    def __init__(self, disk_usage):
        Event.__init__(self)
        # hash of device root path -> DiskUsageSample
        self.disk_usage = disk_usage

class NoProvider(Event):
    """No Provider for an Event"""

    def __init__(self, item, runtime=False, dependees=None, reasons=None, close_matches=None):
        Event.__init__(self)
        self._item = item
        self._runtime = runtime
        self._dependees = dependees
        self._reasons = reasons
        self._close_matches = close_matches

    def getItem(self):
        return self._item

    def isRuntime(self):
        return self._runtime

    def __str__(self):
        msg = ''
        if self._runtime:
            r = "R"
        else:
            r = ""

        extra = ''
        if not self._reasons:
            if self._close_matches:
                extra = ". Close matches:\n  %s" % '\n  '.join(sorted(set(self._close_matches)))

        if self._dependees:
            msg = "Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)%s" % (r, self._item, ", ".join(self._dependees), r, extra)
        else:
            msg = "Nothing %sPROVIDES '%s'%s" % (r, self._item, extra)
        if self._reasons:
            for reason in self._reasons:
                msg += '\n' + reason
        return msg


class MultipleProviders(Event):
    """Multiple Providers"""

    def  __init__(self, item, candidates, runtime = False):
        Event.__init__(self)
        self._item = item
        self._candidates = candidates
        self._is_runtime = runtime

    def isRuntime(self):
        """
        Is this a runtime issue?
        """
        return self._is_runtime

    def getItem(self):
        """
        The name for the to be build item
        """
        return self._item

    def getCandidates(self):
        """
        Get the possible Candidates for a PROVIDER.
        """
        return self._candidates

    def __str__(self):
        msg = "Multiple providers are available for %s%s (%s)" % (self._is_runtime and "runtime " or "",
                            self._item,
                            ", ".join(self._candidates))
        rtime = ""
        if self._is_runtime:
            rtime = "R"
        msg += "\nConsider defining a PREFERRED_%sPROVIDER entry to match %s" % (rtime, self._item)
        return msg

class ParseStarted(OperationStarted):
    """Recipe parsing for the runqueue has begun"""
    def __init__(self, total):
        OperationStarted.__init__(self, "Recipe parsing Started")
        self.total = total

class ParseCompleted(OperationCompleted):
    """Recipe parsing for the runqueue has completed"""
    def __init__(self, cached, parsed, skipped, masked, virtuals, errors, total):
        OperationCompleted.__init__(self, total, "Recipe parsing Completed")
        self.cached = cached
        self.parsed = parsed
        self.skipped = skipped
        self.virtuals = virtuals
        self.masked = masked
        self.errors = errors
        self.sofar = cached + parsed

class ParseProgress(OperationProgress):
    """Recipe parsing progress"""
    def __init__(self, current, total):
        OperationProgress.__init__(self, current, total, "Recipe parsing")


class CacheLoadStarted(OperationStarted):
    """Loading of the dependency cache has begun"""
    def __init__(self, total):
        OperationStarted.__init__(self, "Loading cache Started")
        self.total = total

class CacheLoadProgress(OperationProgress):
    """Cache loading progress"""
    def __init__(self, current, total):
        OperationProgress.__init__(self, current, total, "Loading cache")

class CacheLoadCompleted(OperationCompleted):
    """Cache loading is complete"""
    def __init__(self, total, num_entries):
        OperationCompleted.__init__(self, total, "Loading cache Completed")
        self.num_entries = num_entries

class TreeDataPreparationStarted(OperationStarted):
    """Tree data preparation started"""
    def __init__(self):
        OperationStarted.__init__(self, "Preparing tree data Started")

class TreeDataPreparationProgress(OperationProgress):
    """Tree data preparation is in progress"""
    def __init__(self, current, total):
        OperationProgress.__init__(self, current, total, "Preparing tree data")

class TreeDataPreparationCompleted(OperationCompleted):
    """Tree data preparation completed"""
    def __init__(self, total):
        OperationCompleted.__init__(self, total, "Preparing tree data Completed")

class DepTreeGenerated(Event):
    """
    Event when a dependency tree has been generated
    """

    def __init__(self, depgraph):
        Event.__init__(self)
        self._depgraph = depgraph

class TargetsTreeGenerated(Event):
    """
    Event when a set of buildable targets has been generated
    """
    def __init__(self, model):
        Event.__init__(self)
        self._model = model

class ReachableStamps(Event):
    """
    An event listing all stamps reachable after parsing
    which the metadata may use to clean up stale data
    """

    def __init__(self, stamps):
        Event.__init__(self)
        self.stamps = stamps

class FilesMatchingFound(Event):
    """
    Event when a list of files matching the supplied pattern has
    been generated
    """
    def __init__(self, pattern, matches):
        Event.__init__(self)
        self._pattern = pattern
        self._matches = matches

class ConfigFilesFound(Event):
    """
    Event when a list of appropriate config files has been generated
    """
    def __init__(self, variable, values):
        Event.__init__(self)
        self._variable = variable
        self._values = values

class ConfigFilePathFound(Event):
    """
    Event when a path for a config file has been found
    """
    def __init__(self, path):
        Event.__init__(self)
        self._path = path

class MsgBase(Event):
    """Base class for messages"""

    def __init__(self, msg):
        self._message = msg
        Event.__init__(self)

class MsgDebug(MsgBase):
    """Debug Message"""

class MsgNote(MsgBase):
    """Note Message"""

class MsgWarn(MsgBase):
    """Warning Message"""

class MsgError(MsgBase):
    """Error Message"""

class MsgFatal(MsgBase):
    """Fatal Message"""

class MsgPlain(MsgBase):
    """General output"""

class LogExecTTY(Event):
    """Send event containing program to spawn on tty of the logger"""
    def __init__(self, msg, prog, sleep_delay, retries):
        Event.__init__(self)
        self.msg = msg
        self.prog = prog
        self.sleep_delay = sleep_delay
        self.retries = retries

class LogHandler(logging.Handler):
    """Dispatch logging messages as bitbake events"""

    def emit(self, record):
        if record.exc_info:
            etype, value, tb = record.exc_info
            if hasattr(tb, 'tb_next'):
                tb = list(bb.exceptions.extract_traceback(tb, context=3))
            # Need to turn the value into something the logging system can pickle
            record.bb_exc_info = (etype, value, tb)
            record.bb_exc_formatted = bb.exceptions.format_exception(etype, value, tb, limit=5)
            value = str(value)
            record.exc_info = None
        fire(record, None)

    def filter(self, record):
        record.taskpid = worker_pid
        return True

class MetadataEvent(Event):
    """
    Generic event that target for OE-Core classes
    to report information during asynchrous execution
    """
    def __init__(self, eventtype, eventdata):
        Event.__init__(self)
        self.type = eventtype
        self._localdata = eventdata

class ProcessStarted(Event):
    """
    Generic process started event (usually part of the initial startup)
    where further progress events will be delivered
    """
    def __init__(self, processname, total):
        Event.__init__(self)
        self.processname = processname
        self.total = total

class ProcessProgress(Event):
    """
    Generic process progress event (usually part of the initial startup)
    """
    def __init__(self, processname, progress):
        Event.__init__(self)
        self.processname = processname
        self.progress = progress

class ProcessFinished(Event):
    """
    Generic process finished event (usually part of the initial startup)
    """
    def __init__(self, processname):
        Event.__init__(self)
        self.processname = processname

class SanityCheck(Event):
    """
    Event to run sanity checks, either raise errors or generate events as return status.
    """
    def __init__(self, generateevents = True):
        Event.__init__(self)
        self.generateevents = generateevents

class SanityCheckPassed(Event):
    """
    Event to indicate sanity check has passed
    """

class SanityCheckFailed(Event):
    """
    Event to indicate sanity check has failed
    """
    def __init__(self, msg, network_error=False):
        Event.__init__(self)
        self._msg = msg
        self._network_error = network_error

class NetworkTest(Event):
    """
    Event to run network connectivity tests, either raise errors or generate events as return status.
    """
    def __init__(self, generateevents = True):
        Event.__init__(self)
        self.generateevents = generateevents

class NetworkTestPassed(Event):
    """
    Event to indicate network test has passed
    """

class NetworkTestFailed(Event):
    """
    Event to indicate network test has failed
    """

class FindSigInfoResult(Event):
    """
    Event to return results from findSigInfo command
    """
    def __init__(self, result):
        Event.__init__(self)
        self.result = result
