#!/usr/bin/env python3

# OpenEmbedded Development tool
#
# Copyright (C) 2014-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 sys
import os
import argparse
import glob
import re
import configparser
import subprocess
import logging

basepath = ''
workspace = {}
config = None
context = None


scripts_path = os.path.dirname(os.path.realpath(__file__))
lib_path = scripts_path + '/lib'
sys.path = sys.path + [lib_path]
from devtool import DevtoolError, setup_tinfoil
import scriptutils
import argparse_oe
logger = scriptutils.logger_create('devtool')

plugins = []


class ConfigHandler(object):
    config_file = ''
    config_obj = None
    init_path = ''
    workspace_path = ''

    def __init__(self, filename):
        self.config_file = filename
        self.config_obj = configparser.ConfigParser()

    def get(self, section, option, default=None):
        try:
            ret = self.config_obj.get(section, option)
        except (configparser.NoOptionError, configparser.NoSectionError):
            if default != None:
                ret = default
            else:
                raise
        return ret

    def read(self):
        if os.path.exists(self.config_file):
            self.config_obj.read(self.config_file)

            if self.config_obj.has_option('General', 'init_path'):
                pth = self.get('General', 'init_path')
                self.init_path = os.path.join(basepath, pth)
                if not os.path.exists(self.init_path):
                    logger.error('init_path %s specified in config file cannot be found' % pth)
                    return False
        else:
            self.config_obj.add_section('General')

        self.workspace_path = self.get('General', 'workspace_path', os.path.join(basepath, 'workspace'))
        return True


    def write(self):
        logger.debug('writing to config file %s' % self.config_file)
        self.config_obj.set('General', 'workspace_path', self.workspace_path)
        with open(self.config_file, 'w') as f:
            self.config_obj.write(f)

    def set(self, section, option, value):
        if not self.config_obj.has_section(section):
            self.config_obj.add_section(section)
        self.config_obj.set(section, option, value)

class Context:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)


def read_workspace():
    global workspace
    workspace = {}
    if not os.path.exists(os.path.join(config.workspace_path, 'conf', 'layer.conf')):
        if context.fixed_setup:
            logger.error("workspace layer not set up")
            sys.exit(1)
        else:
            logger.info('Creating workspace layer in %s' % config.workspace_path)
            _create_workspace(config.workspace_path, config, basepath)
    if not context.fixed_setup:
        _enable_workspace_layer(config.workspace_path, config, basepath)

    logger.debug('Reading workspace in %s' % config.workspace_path)
    externalsrc_re = re.compile(r'^EXTERNALSRC(_pn-([^ =]+))? *= *"([^"]*)"$')
    for fn in glob.glob(os.path.join(config.workspace_path, 'appends', '*.bbappend')):
        with open(fn, 'r') as f:
            pnvalues = {}
            for line in f:
                res = externalsrc_re.match(line.rstrip())
                if res:
                    recipepn = os.path.splitext(os.path.basename(fn))[0].split('_')[0]
                    pn = res.group(2) or recipepn
                    # Find the recipe file within the workspace, if any
                    bbfile = os.path.basename(fn).replace('.bbappend', '.bb').replace('%', '*')
                    recipefile = glob.glob(os.path.join(config.workspace_path,
                                                        'recipes',
                                                        recipepn,
                                                        bbfile))
                    if recipefile:
                        recipefile = recipefile[0]
                    pnvalues['srctree'] = res.group(3)
                    pnvalues['bbappend'] = fn
                    pnvalues['recipefile'] = recipefile
                elif line.startswith('# srctreebase: '):
                    pnvalues['srctreebase'] = line.split(':', 1)[1].strip()
            if pnvalues:
                if not pnvalues.get('srctreebase', None):
                    pnvalues['srctreebase'] = pnvalues['srctree']
                logger.debug('Found recipe %s' % pnvalues)
                workspace[pn] = pnvalues

def create_workspace(args, config, basepath, workspace):
    if args.layerpath:
        workspacedir = os.path.abspath(args.layerpath)
    else:
        workspacedir = os.path.abspath(os.path.join(basepath, 'workspace'))
    _create_workspace(workspacedir, config, basepath)
    if not args.create_only:
        _enable_workspace_layer(workspacedir, config, basepath)

def _create_workspace(workspacedir, config, basepath):
    import bb

    confdir = os.path.join(workspacedir, 'conf')
    if os.path.exists(os.path.join(confdir, 'layer.conf')):
        logger.info('Specified workspace already set up, leaving as-is')
    else:
        # Add a config file
        bb.utils.mkdirhier(confdir)
        with open(os.path.join(confdir, 'layer.conf'), 'w') as f:
            f.write('# ### workspace layer auto-generated by devtool ###\n')
            f.write('BBPATH =. "$' + '{LAYERDIR}:"\n')
            f.write('BBFILES += "$' + '{LAYERDIR}/recipes/*/*.bb \\\n')
            f.write('            $' + '{LAYERDIR}/appends/*.bbappend"\n')
            f.write('BBFILE_COLLECTIONS += "workspacelayer"\n')
            f.write('BBFILE_PATTERN_workspacelayer = "^$' + '{LAYERDIR}/"\n')
            f.write('BBFILE_PATTERN_IGNORE_EMPTY_workspacelayer = "1"\n')
            f.write('BBFILE_PRIORITY_workspacelayer = "99"\n')
            f.write('LAYERSERIES_COMPAT_workspacelayer = "${LAYERSERIES_COMPAT_core}"\n')
        # Add a README file
        with open(os.path.join(workspacedir, 'README'), 'w') as f:
            f.write('This layer was created by the OpenEmbedded devtool utility in order to\n')
            f.write('contain recipes and bbappends that are currently being worked on. The idea\n')
            f.write('is that the contents is temporary - once you have finished working on a\n')
            f.write('recipe you use the appropriate method to move the files you have been\n')
            f.write('working on to a proper layer. In most instances you should use the\n')
            f.write('devtool utility to manage files within it rather than modifying files\n')
            f.write('directly (although recipes added with "devtool add" will often need\n')
            f.write('direct modification.)\n')
            f.write('\nIf you no longer need to use devtool or the workspace layer\'s contents\n')
            f.write('you can remove the path to this workspace layer from your conf/bblayers.conf\n')
            f.write('file (and then delete the layer, if you wish).\n')
            f.write('\nNote that by default, if devtool fetches and unpacks source code, it\n')
            f.write('will place it in a subdirectory of a "sources" subdirectory of the\n')
            f.write('layer. If you prefer it to be elsewhere you can specify the source\n')
            f.write('tree path on the command line.\n')

def _enable_workspace_layer(workspacedir, config, basepath):
    """Ensure the workspace layer is in bblayers.conf"""
    import bb
    bblayers_conf = os.path.join(basepath, 'conf', 'bblayers.conf')
    if not os.path.exists(bblayers_conf):
        logger.error('Unable to find bblayers.conf')
        return
    if os.path.abspath(workspacedir) != os.path.abspath(config.workspace_path):
        removedir = config.workspace_path
    else:
        removedir = None
    _, added = bb.utils.edit_bblayers_conf(bblayers_conf, workspacedir, removedir)
    if added:
        logger.info('Enabling workspace layer in bblayers.conf')
    if config.workspace_path != workspacedir:
        # Update our config to point to the new location
        config.workspace_path = workspacedir
        config.write()


def main():
    global basepath
    global config
    global context

    if sys.getfilesystemencoding() != "utf-8":
        sys.exit("Please use a locale setting which supports utf-8.\nPython can't change the filesystem locale after loading so we need a utf-8 when python starts or things won't work.")

    context = Context(fixed_setup=False)

    # Default basepath
    basepath = os.path.dirname(os.path.abspath(__file__))

    parser = argparse_oe.ArgumentParser(description="OpenEmbedded development tool",
                                        add_help=False,
                                        epilog="Use %(prog)s <subcommand> --help to get help on a specific command")
    parser.add_argument('--basepath', help='Base directory of SDK / build directory')
    parser.add_argument('--bbpath', help='Explicitly specify the BBPATH, rather than getting it from the metadata')
    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')

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

    if global_args.basepath:
        # Override
        basepath = global_args.basepath
        if os.path.exists(os.path.join(basepath, '.devtoolbase')):
            context.fixed_setup = True
    else:
        pth = basepath
        while pth != '' and pth != os.sep:
            if os.path.exists(os.path.join(pth, '.devtoolbase')):
                context.fixed_setup = True
                basepath = pth
                break
            pth = os.path.dirname(pth)

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

    logger.debug('Using basepath %s' % basepath)

    config = ConfigHandler(os.path.join(basepath, 'conf', 'devtool.conf'))
    if not config.read():
        return -1
    context.config = config

    bitbake_subdir = config.get('General', 'bitbake_subdir', '')
    if bitbake_subdir:
        # Normally set for use within the SDK
        logger.debug('Using bitbake subdir %s' % bitbake_subdir)
        sys.path.insert(0, os.path.join(basepath, bitbake_subdir, 'lib'))
        core_meta_subdir = config.get('General', 'core_meta_subdir')
        sys.path.insert(0, os.path.join(basepath, core_meta_subdir, 'lib'))
    else:
        # Standard location
        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('Using standard bitbake path %s' % bitbakepath)
        scriptpath.add_oe_lib_path()

    scriptutils.logger_setup_color(logger, global_args.color)

    if global_args.bbpath is None:
        try:
            tinfoil = setup_tinfoil(config_only=True, basepath=basepath)
            try:
                global_args.bbpath = tinfoil.config_data.getVar('BBPATH')
            finally:
                tinfoil.shutdown()
        except bb.BBHandledException:
            return 2

    # Search BBPATH first to allow layers to override plugins in scripts_path
    for path in global_args.bbpath.split(':') + [scripts_path]:
        pluginpath = os.path.join(path, 'lib', 'devtool')
        scriptutils.load_plugins(logger, plugins, pluginpath)

    subparsers = parser.add_subparsers(dest="subparser_name", title='subcommands', metavar='<subcommand>')
    subparsers.required = True

    subparsers.add_subparser_group('sdk', 'SDK maintenance', -2)
    subparsers.add_subparser_group('advanced', 'Advanced', -1)
    subparsers.add_subparser_group('starting', 'Beginning work on a recipe', 100)
    subparsers.add_subparser_group('info', 'Getting information')
    subparsers.add_subparser_group('working', 'Working on a recipe in the workspace')
    subparsers.add_subparser_group('testbuild', 'Testing changes on target')

    if not context.fixed_setup:
        parser_create_workspace = subparsers.add_parser('create-workspace',
                                                        help='Set up workspace in an alternative location',
                                                        description='Sets up a new workspace. NOTE: other devtool subcommands will create a workspace automatically as needed, so you only need to use %(prog)s if you want to specify where the workspace should be located.',
                                                        group='advanced')
        parser_create_workspace.add_argument('layerpath', nargs='?', help='Path in which the workspace layer should be created')
        parser_create_workspace.add_argument('--create-only', action="store_true", help='Only create the workspace layer, do not alter configuration')
        parser_create_workspace.set_defaults(func=create_workspace, no_workspace=True)

    for plugin in plugins:
        if hasattr(plugin, 'register_commands'):
            plugin.register_commands(subparsers, context)

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

    if not getattr(args, 'no_workspace', False):
        read_workspace()

    try:
        ret = args.func(args, config, basepath, workspace)
    except DevtoolError as err:
        if str(err):
            logger.error(str(err))
        ret = err.exitcode
    except argparse_oe.ArgumentUsageError as ae:
        parser.error_subcommand(ae.message, ae.subcommand)

    return ret


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