#!/usr/bin/env python3

# Recipe creation tool
#
# Copyright (C) 2014 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
#

import sys
import os
import argparse
import glob
import logging

scripts_path = os.path.dirname(os.path.realpath(__file__))
lib_path = scripts_path + '/lib'
sys.path = sys.path + [lib_path]
import scriptutils
import argparse_oe
logger = scriptutils.logger_create('recipetool')

plugins = []

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

def main():

    if not os.environ.get('BUILDDIR', ''):
        logger.error("This script can only be run after initialising the build environment (e.g. by using oe-init-build-env)")
        sys.exit(1)

    parser = argparse_oe.ArgumentParser(description="OpenEmbedded recipe tool",
                                        add_help=False,
                                        epilog="Use %(prog)s <subcommand> --help to get help on a specific command")
    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)

    import scriptpath
    bitbakepath = scriptpath.add_bitbake_lib_path()
    if not bitbakepath:
        logger.error("Unable to find bitbake by searching parent directory of this script or PATH")
        sys.exit(1)
    logger.debug('Found bitbake path: %s' % bitbakepath)
    scriptpath.add_oe_lib_path()

    scriptutils.logger_setup_color(logger, global_args.color)

    tinfoil = tinfoil_init(False)
    try:
        for path in (tinfoil.config_data.getVar('BBPATH').split(':')
                     + [scripts_path]):
            pluginpath = os.path.join(path, 'lib', 'recipetool')
            scriptutils.load_plugins(logger, plugins, pluginpath)

        registered = False
        for plugin in plugins:
            if hasattr(plugin, 'register_commands'):
                registered = True
                plugin.register_commands(subparsers)
            elif hasattr(plugin, 'register_command'):
                # Legacy function name
                registered = True
                plugin.register_command(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)

        try:
            if getattr(args, 'parserecipes', False):
                tinfoil.config_data.disableTracking()
                tinfoil.parseRecipes()
                tinfoil.config_data.enableTracking()
            ret = args.func(args)
        except bb.BBHandledException:
            ret = 1
    finally:
        tinfoil.shutdown()

    return ret


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