#!/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
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import logging
import os
import sys
import argparse

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

import bb.tinfoil


def tinfoil_init(parserecipes):
    import bb.tinfoil
    tinfoil = bb.tinfoil.Tinfoil(tracking=True)
    tinfoil.prepare(not parserecipes)
    tinfoil.logger.setLevel(logger.getEffectiveLevel())
    return tinfoil


def logger_create(name, output=sys.stderr):
    logger = logging.getLogger(name)
    loggerhandler = logging.StreamHandler(output)
    loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
    logger.addHandler(loggerhandler)
    logger.setLevel(logging.INFO)
    return logger

def logger_setup_color(logger, color='auto'):
    from bb.msg import BBLogFormatter
    console = logging.StreamHandler(sys.stdout)
    formatter = BBLogFormatter("%(levelname)s: %(message)s")
    console.setFormatter(formatter)
    logger.handlers = [console]
    if color == 'always' or (color == 'auto' and console.stream.isatty()):
        formatter.enable_color()


logger = 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('--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)

    logger_setup_color(logger, global_args.color)

    plugins = []
    tinfoil = tinfoil_init(False)
    try:
        for path in ([topdir] +
                    tinfoil.config_data.getVar('BBPATH', True).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.parseRecipes()
            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)
