#!/usr/bin/env python3

# This script has subcommands which operate against your bitbake layers, either
# displaying useful information, or acting against them.
# See the help output for details on available commands.

# Copyright (C) 2011 Mentor Graphics Corporation
# Copyright (C) 2011-2015 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
#

import logging
import os
import sys
import argparse
import warnings
warnings.simplefilter("default")

__version__ = "2.19.1"

bindir = os.path.dirname(__file__)
toolname = os.path.basename(__file__).split(".")[0]
topdir = os.path.dirname(bindir)
sys.path[0:0] = [os.path.join(topdir, 'lib')]

import bb.tinfoil
import bb.cooker
import bb.msg
from bb import __version__ as libbb_version

if __version__ != libbb_version:
    sys.exit("Bitbake library version and program version mismatch!")

logger = bb.msg.logger_create(toolname, sys.stdout)

def main():
    parser = argparse.ArgumentParser(
        description={"bitbake-layers":"BitBake layers utility", "bitbake-config-build":"BitBake build configuration utility"}[toolname],
        epilog="Use %(prog)s <subcommand> --help to get help on a specific command",
        add_help=False)
    parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
    parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true')
    if toolname == "bitbake-layers":
        parser.add_argument('-F', '--force', help='Forced execution: can be specified multiple times. -F will force add without recipe parse verification and -FF will additionally force the run without layer parsing.', action='count')
    parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR')

    # Set the default for --force here rather than above so that it is always
    # defined even if the option is not available.
    parser.set_defaults(force=0)

    global_args, unparsed_args = parser.parse_known_args()

    # Help is added here rather than via add_help=True, as we don't want it to
    # be handled by parse_known_args()
    parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS,
                        help='show this help message and exit')
    subparsers = parser.add_subparsers(title='subcommands', metavar='<subcommand>')
    subparsers.required = True

    if global_args.debug:
        logger.setLevel(logging.DEBUG)
    elif global_args.quiet:
        logger.setLevel(logging.ERROR)

    # Need to re-run logger_create with color argument
    # (will be the same logger since it has the same name)
    bb.msg.logger_create('bitbake-layers', output=sys.stdout,
                         color=global_args.color,
                         level=logger.getEffectiveLevel())

    plugins = []
    with bb.tinfoil.Tinfoil(tracking=True) as tinfoil:
        tinfoil.logger.setLevel(logger.getEffectiveLevel())

        if global_args.force > 1:
            bbpaths = []
        else:
            if toolname == "bitbake-config-build":
                extra_features = [bb.cooker.CookerFeatures.SKIP_FRAGMENTS]
            else:
                extra_features = None
            tinfoil.prepare(True, extra_features=extra_features)
            bbpaths = tinfoil.config_data.getVar('BBPATH').split(':')

        for path in ([topdir] + bbpaths):
            pluginbasepath = {"bitbake-layers":'bblayers', 'bitbake-config-build':'bbconfigbuild'}[toolname]
            pluginpath = os.path.join(path, 'lib', pluginbasepath)
            bb.utils.load_plugins(logger, plugins, pluginpath)

        registered = False
        for plugin in plugins:
            if hasattr(plugin, 'tinfoil_init') and global_args.force <= 1:
                plugin.tinfoil_init(tinfoil)
            if hasattr(plugin, 'register_commands'):
                registered = True
                plugin.register_commands(subparsers)

        if not registered:
            logger.error("No commands registered - missing plugins?")
            sys.exit(1)

        args = parser.parse_args(unparsed_args, namespace=global_args)

        if getattr(args, 'parserecipes', False):
            tinfoil.config_data.disableTracking()
            tinfoil.parse_recipes()
            tinfoil.config_data.enableTracking()

        return args.func(args)


if __name__ == "__main__":
    try:
        ret = main()
    except bb.BBHandledException:
        ret = 1
    except Exception:
        ret = 1
        import traceback
        traceback.print_exc()
    sys.exit(ret)
