#
# Copyright (C) 2003, 2004  Chris Larson
# Copyright (C) 2003, 2004  Phil Blundell
# Copyright (C) 2003 - 2005 Michael 'Mickey' Lauer
# Copyright (C) 2005        Holger Hans Peter Freyther
# Copyright (C) 2005        ROAD GmbH
# Copyright (C) 2006        Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
#

import os
import sys
import logging
import optparse
import warnings
import fcntl
import time
import traceback

import bb
from bb import event
import bb.msg
from bb import cooker
from bb import ui
from bb import server
from bb import cookerdata

import bb.server.process
import bb.server.xmlrpcclient

logger = logging.getLogger("BitBake")

class BBMainException(Exception):
    pass

class BBMainFatal(bb.BBHandledException):
    pass

def present_options(optionlist):
    if len(optionlist) > 1:
        return ' or '.join([', '.join(optionlist[:-1]), optionlist[-1]])
    else:
        return optionlist[0]

class BitbakeHelpFormatter(optparse.IndentedHelpFormatter):
    def format_option(self, option):
        # We need to do this here rather than in the text we supply to
        # add_option() because we don't want to call list_extension_modules()
        # on every execution (since it imports all of the modules)
        # Note also that we modify option.help rather than the returned text
        # - this is so that we don't have to re-format the text ourselves
        if option.dest == 'ui':
            valid_uis = list_extension_modules(bb.ui, 'main')
            option.help = option.help.replace('@CHOICES@', present_options(valid_uis))

        return optparse.IndentedHelpFormatter.format_option(self, option)

def list_extension_modules(pkg, checkattr):
    """
    Lists extension modules in a specific Python package
    (e.g. UIs, servers). NOTE: Calling this function will import all of the
    submodules of the specified module in order to check for the specified
    attribute; this can have unusual side-effects. As a result, this should
    only be called when displaying help text or error messages.
    Parameters:
        pkg: previously imported Python package to list
        checkattr: attribute to look for in module to determine if it's valid
            as the type of extension you are looking for
    """
    import pkgutil
    pkgdir = os.path.dirname(pkg.__file__)

    modules = []
    for _, modulename, _ in pkgutil.iter_modules([pkgdir]):
        if os.path.isdir(os.path.join(pkgdir, modulename)):
            # ignore directories
            continue
        try:
            module = __import__(pkg.__name__, fromlist=[modulename])
        except:
            # If we can't import it, it's not valid
            continue
        module_if = getattr(module, modulename)
        if getattr(module_if, 'hidden_extension', False):
            continue
        if not checkattr or hasattr(module_if, checkattr):
            modules.append(modulename)
    return modules

def import_extension_module(pkg, modulename, checkattr):
    try:
        # Dynamically load the UI based on the ui name. Although we
        # suggest a fixed set this allows you to have flexibility in which
        # ones are available.
        module = __import__(pkg.__name__, fromlist=[modulename])
        return getattr(module, modulename)
    except AttributeError:
        modules = present_options(list_extension_modules(pkg, checkattr))
        raise BBMainException('FATAL: Unable to import extension module "%s" from %s. '
                              'Valid extension modules: %s' % (modulename, pkg.__name__, modules))

# Display bitbake/OE warnings via the BitBake.Warnings logger, ignoring others"""
warnlog = logging.getLogger("BitBake.Warnings")
_warnings_showwarning = warnings.showwarning
def _showwarning(message, category, filename, lineno, file=None, line=None):
    if file is not None:
        if _warnings_showwarning is not None:
            _warnings_showwarning(message, category, filename, lineno, file, line)
    else:
        s = warnings.formatwarning(message, category, filename, lineno)
        warnlog.warning(s)

warnings.showwarning = _showwarning

def create_bitbake_parser():
    parser = optparse.OptionParser(
        formatter=BitbakeHelpFormatter(),
        version="BitBake Build Tool Core version %s" % bb.__version__,
        usage="""%prog [options] [recipename/target recipe:do_task ...]

    Executes the specified task (default is 'build') for a given set of target recipes (.bb files).
    It is assumed there is a conf/bblayers.conf available in cwd or in BBPATH which
    will provide the layer, BBFILES and other configuration information.""")

    parser.add_option("-b", "--buildfile", action="store", dest="buildfile", default=None,
                      help="Execute tasks from a specific .bb recipe directly. WARNING: Does "
                           "not handle any dependencies from other recipes.")

    parser.add_option("-k", "--continue", action="store_false", dest="abort", default=True,
                      help="Continue as much as possible after an error. While the target that "
                           "failed and anything depending on it cannot be built, as much as "
                           "possible will be built before stopping.")

    parser.add_option("-f", "--force", action="store_true", dest="force", default=False,
                      help="Force the specified targets/task to run (invalidating any "
                           "existing stamp file).")

    parser.add_option("-c", "--cmd", action="store", dest="cmd",
                      help="Specify the task to execute. The exact options available "
                           "depend on the metadata. Some examples might be 'compile'"
                           " or 'populate_sysroot' or 'listtasks' may give a list of "
                           "the tasks available.")

    parser.add_option("-C", "--clear-stamp", action="store", dest="invalidate_stamp",
                      help="Invalidate the stamp for the specified task such as 'compile' "
                           "and then run the default task for the specified target(s).")

    parser.add_option("-r", "--read", action="append", dest="prefile", default=[],
                      help="Read the specified file before bitbake.conf.")

    parser.add_option("-R", "--postread", action="append", dest="postfile", default=[],
                      help="Read the specified file after bitbake.conf.")

    parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
                      help="Enable tracing of shell tasks (with 'set -x'). "
                           "Also print bb.note(...) messages to stdout (in "
                           "addition to writing them to ${T}/log.do_<task>).")

    parser.add_option("-D", "--debug", action="count", dest="debug", default=0,
                      help="Increase the debug level. You can specify this "
                           "more than once. -D sets the debug level to 1, "
                           "where only bb.debug(1, ...) messages are printed "
                           "to stdout; -DD sets the debug level to 2, where "
                           "both bb.debug(1, ...) and bb.debug(2, ...) "
                           "messages are printed; etc. Without -D, no debug "
                           "messages are printed. Note that -D only affects "
                           "output to stdout. All debug messages are written "
                           "to ${T}/log.do_taskname, regardless of the debug "
                           "level.")

    parser.add_option("-q", "--quiet", action="count", dest="quiet", default=0,
                      help="Output less log message data to the terminal. You can specify this more than once.")

    parser.add_option("-n", "--dry-run", action="store_true", dest="dry_run", default=False,
                      help="Don't execute, just go through the motions.")

    parser.add_option("-S", "--dump-signatures", action="append", dest="dump_signatures",
                      default=[], metavar="SIGNATURE_HANDLER",
                      help="Dump out the signature construction information, with no task "
                           "execution. The SIGNATURE_HANDLER parameter is passed to the "
                           "handler. Two common values are none and printdiff but the handler "
                           "may define more/less. none means only dump the signature, printdiff"
                           " means compare the dumped signature with the cached one.")

    parser.add_option("-p", "--parse-only", action="store_true",
                      dest="parse_only", default=False,
                      help="Quit after parsing the BB recipes.")

    parser.add_option("-s", "--show-versions", action="store_true",
                      dest="show_versions", default=False,
                      help="Show current and preferred versions of all recipes.")

    parser.add_option("-e", "--environment", action="store_true",
                      dest="show_environment", default=False,
                      help="Show the global or per-recipe environment complete with information"
                           " about where variables were set/changed.")

    parser.add_option("-g", "--graphviz", action="store_true", dest="dot_graph", default=False,
                      help="Save dependency tree information for the specified "
                           "targets in the dot syntax.")

    parser.add_option("-I", "--ignore-deps", action="append",
                      dest="extra_assume_provided", default=[],
                      help="Assume these dependencies don't exist and are already provided "
                           "(equivalent to ASSUME_PROVIDED). Useful to make dependency "
                           "graphs more appealing")

    parser.add_option("-l", "--log-domains", action="append", dest="debug_domains", default=[],
                      help="Show debug logging for the specified logging domains")

    parser.add_option("-P", "--profile", action="store_true", dest="profile", default=False,
                      help="Profile the command and save reports.")

    # @CHOICES@ is substituted out by BitbakeHelpFormatter above
    parser.add_option("-u", "--ui", action="store", dest="ui",
                      default=os.environ.get('BITBAKE_UI', 'knotty'),
                      help="The user interface to use (@CHOICES@ - default %default).")

    parser.add_option("", "--token", action="store", dest="xmlrpctoken",
                      default=os.environ.get("BBTOKEN"),
                      help="Specify the connection token to be used when connecting "
                           "to a remote server.")

    parser.add_option("", "--revisions-changed", action="store_true",
                      dest="revisions_changed", default=False,
                      help="Set the exit code depending on whether upstream floating "
                           "revisions have changed or not.")

    parser.add_option("", "--server-only", action="store_true",
                      dest="server_only", default=False,
                      help="Run bitbake without a UI, only starting a server "
                           "(cooker) process.")

    parser.add_option("-B", "--bind", action="store", dest="bind", default=False,
                      help="The name/address for the bitbake xmlrpc server to bind to.")

    parser.add_option("-T", "--idle-timeout", type=float, dest="server_timeout",
                      default=os.getenv("BB_SERVER_TIMEOUT"),
                      help="Set timeout to unload bitbake server due to inactivity, "
                           "set to -1 means no unload, "
                           "default: Environment variable BB_SERVER_TIMEOUT.")

    parser.add_option("", "--no-setscene", action="store_true",
                      dest="nosetscene", default=False,
                      help="Do not run any setscene tasks. sstate will be ignored and "
                           "everything needed, built.")

    parser.add_option("", "--skip-setscene", action="store_true",
                      dest="skipsetscene", default=False,
                      help="Skip setscene tasks if they would be executed. Tasks previously "
                           "restored from sstate will be kept, unlike --no-setscene")

    parser.add_option("", "--setscene-only", action="store_true",
                      dest="setsceneonly", default=False,
                      help="Only run setscene tasks, don't run any real tasks.")

    parser.add_option("", "--remote-server", action="store", dest="remote_server",
                      default=os.environ.get("BBSERVER"),
                      help="Connect to the specified server.")

    parser.add_option("-m", "--kill-server", action="store_true",
                      dest="kill_server", default=False,
                      help="Terminate any running bitbake server.")

    parser.add_option("", "--observe-only", action="store_true",
                      dest="observe_only", default=False,
                      help="Connect to a server as an observing-only client.")

    parser.add_option("", "--status-only", action="store_true",
                      dest="status_only", default=False,
                      help="Check the status of the remote bitbake server.")

    parser.add_option("-w", "--write-log", action="store", dest="writeeventlog",
                      default=os.environ.get("BBEVENTLOG"),
                      help="Writes the event log of the build to a bitbake event json file. "
                           "Use '' (empty string) to assign the name automatically.")

    parser.add_option("", "--runall", action="append", dest="runall",
                      help="Run the specified task for any recipe in the taskgraph of the specified target (even if it wouldn't otherwise have run).")

    parser.add_option("", "--runonly", action="append", dest="runonly",
                      help="Run only the specified task within the taskgraph of the specified targets (and any task dependencies those tasks may have).")
    return parser


class BitBakeConfigParameters(cookerdata.ConfigParameters):
    def parseCommandLine(self, argv=sys.argv):
        parser = create_bitbake_parser()
        options, targets = parser.parse_args(argv)

        if options.quiet and options.verbose:
            parser.error("options --quiet and --verbose are mutually exclusive")

        if options.quiet and options.debug:
            parser.error("options --quiet and --debug are mutually exclusive")

        # use configuration files from environment variables
        if "BBPRECONF" in os.environ:
            options.prefile.append(os.environ["BBPRECONF"])

        if "BBPOSTCONF" in os.environ:
            options.postfile.append(os.environ["BBPOSTCONF"])

        # fill in proper log name if not supplied
        if options.writeeventlog is not None and len(options.writeeventlog) == 0:
            from datetime import datetime
            eventlog = "bitbake_eventlog_%s.json" % datetime.now().strftime("%Y%m%d%H%M%S")
            options.writeeventlog = eventlog

        if options.bind:
            try:
                #Checking that the port is a number and is a ':' delimited value
                (host, port) = options.bind.split(':')
                port = int(port)
            except (ValueError,IndexError):
                raise BBMainException("FATAL: Malformed host:port bind parameter")
            options.xmlrpcinterface = (host, port)
        else:
            options.xmlrpcinterface = (None, 0)

        return options, targets[1:]


def bitbake_main(configParams, configuration):

    # Python multiprocessing requires /dev/shm on Linux
    if sys.platform.startswith('linux') and not os.access('/dev/shm', os.W_OK | os.X_OK):
        raise BBMainException("FATAL: /dev/shm does not exist or is not writable")

    # Unbuffer stdout to avoid log truncation in the event
    # of an unorderly exit as well as to provide timely
    # updates to log files for use with tail
    try:
        if sys.stdout.name == '<stdout>':
            # Reopen with O_SYNC (unbuffered)
            fl = fcntl.fcntl(sys.stdout.fileno(), fcntl.F_GETFL)
            fl |= os.O_SYNC
            fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, fl)
    except:
        pass

    if configParams.server_only and configParams.remote_server:
            raise BBMainException("FATAL: The '--server-only' option conflicts with %s.\n" %
                                  ("the BBSERVER environment variable" if "BBSERVER" in os.environ \
                                   else "the '--remote-server' option"))

    if configParams.observe_only and not (configParams.remote_server or configParams.bind):
        raise BBMainException("FATAL: '--observe-only' can only be used by UI clients "
                              "connecting to a server.\n")

    if "BBDEBUG" in os.environ:
        level = int(os.environ["BBDEBUG"])
        if level > configParams.debug:
            configParams.debug = level

    bb.msg.init_msgconfig(configParams.verbose, configParams.debug,
                          configParams.debug_domains)

    server_connection, ui_module = setup_bitbake(configParams)
    # No server connection
    if server_connection is None:
        if configParams.status_only:
            return 1
        if configParams.kill_server:
            return 0

    if not configParams.server_only:
        if configParams.status_only:
            server_connection.terminate()
            return 0

        try:
            for event in bb.event.ui_queue:
                server_connection.events.queue_event(event)
            bb.event.ui_queue = []

            return ui_module.main(server_connection.connection, server_connection.events,
                                  configParams)
        finally:
            server_connection.terminate()
    else:
        return 0

    return 1

def setup_bitbake(configParams, extrafeatures=None):
    # Ensure logging messages get sent to the UI as events
    handler = bb.event.LogHandler()
    if not configParams.status_only:
        # In status only mode there are no logs and no UI
        logger.addHandler(handler)

    if configParams.server_only:
        featureset = []
        ui_module = None
    else:
        ui_module = import_extension_module(bb.ui, configParams.ui, 'main')
        # Collect the feature set for the UI
        featureset = getattr(ui_module, "featureSet", [])

    if extrafeatures:
        for feature in extrafeatures:
            if not feature in featureset:
                featureset.append(feature)

    server_connection = None

    # Clear away any spurious environment variables while we stoke up the cooker
    # (done after import_extension_module() above since for example import gi triggers env var usage)
    cleanedvars = bb.utils.clean_environment()

    if configParams.remote_server:
        # Connect to a remote XMLRPC server
        server_connection = bb.server.xmlrpcclient.connectXMLRPC(configParams.remote_server, featureset,
                                                                 configParams.observe_only, configParams.xmlrpctoken)
    else:
        retries = 8
        while retries:
            try:
                topdir, lock = lockBitbake()
                sockname = topdir + "/bitbake.sock"
                if lock:
                    if configParams.status_only or configParams.kill_server:
                        logger.info("bitbake server is not running.")
                        lock.close()
                        return None, None
                    # we start a server with a given featureset
                    logger.info("Starting bitbake server...")
                    # Clear the event queue since we already displayed messages
                    bb.event.ui_queue = []
                    server = bb.server.process.BitBakeServer(lock, sockname, featureset, configParams.server_timeout, configParams.xmlrpcinterface)

                else:
                    logger.info("Reconnecting to bitbake server...")
                    if not os.path.exists(sockname):
                        logger.info("Previous bitbake instance shutting down?, waiting to retry...")
                        i = 0
                        lock = None
                        # Wait for 5s or until we can get the lock
                        while not lock and i < 50:
                            time.sleep(0.1)
                            _, lock = lockBitbake()
                            i += 1
                        if lock:
                            bb.utils.unlockfile(lock)
                        raise bb.server.process.ProcessTimeout("Bitbake still shutting down as socket exists but no lock?")
                if not configParams.server_only:
                    server_connection = bb.server.process.connectProcessServer(sockname, featureset)

                if server_connection or configParams.server_only:
                    break
            except BBMainFatal:
                raise
            except (Exception, bb.server.process.ProcessTimeout, SystemExit) as e:
                # SystemExit does not inherit from the Exception class, needs to be included explicitly
                if not retries:
                    raise
                retries -= 1
                tryno = 8 - retries
                if isinstance(e, (bb.server.process.ProcessTimeout, BrokenPipeError, EOFError, SystemExit)):
                    logger.info("Retrying server connection (#%d)..." % tryno)
                else:
                    logger.info("Retrying server connection (#%d)... (%s)" % (tryno, traceback.format_exc()))

            if not retries:
                bb.fatal("Unable to connect to bitbake server, or start one (server startup failures would be in bitbake-cookerdaemon.log).")
            bb.event.print_ui_queue()
            if retries < 5:
                time.sleep(5)

    if configParams.kill_server:
        server_connection.connection.terminateServer()
        server_connection.terminate()
        bb.event.ui_queue = []
        logger.info("Terminated bitbake server.")
        return None, None

    # Restore the environment in case the UI needs it
    for k in cleanedvars:
        os.environ[k] = cleanedvars[k]

    logger.removeHandler(handler)

    return server_connection, ui_module

def lockBitbake():
    topdir = bb.cookerdata.findTopdir()
    if not topdir:
        bb.error("Unable to find conf/bblayers.conf or conf/bitbake.conf. BBPATH is unset and/or not in a build directory?")
        raise BBMainFatal
    lockfile = topdir + "/bitbake.lock"
    return topdir, bb.utils.lockfile(lockfile, False, False)

