#!/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")

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

import bb.tinfoil
import bb.msg

logger = bb.msg.logger_create('bitbake-layers', sys.stdout)

def main():
    parser = argparse.ArgumentParser(
        description="BitBake layers utility",
        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')
    parser.add_argument('-F', '--force', help='Force add without recipe parse verification', action='store_true')
    parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR')

    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 = []
    tinfoil = bb.tinfoil.Tinfoil(tracking=True)
    tinfoil.logger.setLevel(logger.getEffectiveLevel())
    try:
        tinfoil.prepare(True)
        for path in ([topdir] +
                    tinfoil.config_data.getVar('BBPATH').split(':')):
            pluginpath = os.path.join(path, 'lib', 'bblayers')
            bb.utils.load_plugins(logger, plugins, pluginpath)

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

        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)
    finally:
        tinfoil.shutdown()


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