# Development tool - sdk-update command plugin
#
# Copyright (C) 2015-2016 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
#

import os
import subprocess
import logging
import glob
import shutil
import errno
import sys
import tempfile
import re
from devtool import exec_build_env_command, setup_tinfoil, parse_recipe, DevtoolError

logger = logging.getLogger('devtool')

def parse_locked_sigs(sigfile_path):
    """Return <pn:task>:<hash> dictionary"""
    sig_dict = {}
    with open(sigfile_path) as f:
        lines = f.readlines()
        for line in lines:
            if ':' in line:
                taskkey, _, hashval = line.rpartition(':')
                sig_dict[taskkey.strip()] = hashval.split()[0]
    return sig_dict

def generate_update_dict(sigfile_new, sigfile_old):
    """Return a dict containing <pn:task>:<hash> which indicates what need to be updated"""
    update_dict = {}
    sigdict_new = parse_locked_sigs(sigfile_new)
    sigdict_old = parse_locked_sigs(sigfile_old)
    for k in sigdict_new:
        if k not in sigdict_old:
            update_dict[k] = sigdict_new[k]
            continue
        if sigdict_new[k] != sigdict_old[k]:
            update_dict[k] = sigdict_new[k]
            continue
    return update_dict

def get_sstate_objects(update_dict, sstate_dir):
    """Return a list containing sstate objects which are to be installed"""
    sstate_objects = []
    for k in update_dict:
        files = set()
        hashval = update_dict[k]
        p = sstate_dir + '/' + hashval[:2] + '/*' + hashval + '*.tgz'
        files |= set(glob.glob(p))
        p = sstate_dir + '/*/' + hashval[:2] + '/*' + hashval + '*.tgz'
        files |= set(glob.glob(p))
        files = list(files)
        if len(files) == 1:
            sstate_objects.extend(files)
        elif len(files) > 1:
            logger.error("More than one matching sstate object found for %s" % hashval)

    return sstate_objects

def mkdir(d):
    try:
        os.makedirs(d)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise e

def install_sstate_objects(sstate_objects, src_sdk, dest_sdk):
    """Install sstate objects into destination SDK"""
    sstate_dir = os.path.join(dest_sdk, 'sstate-cache')
    if not os.path.exists(sstate_dir):
        logger.error("Missing sstate-cache directory in %s, it might not be an extensible SDK." % dest_sdk)
        raise
    for sb in sstate_objects:
        dst = sb.replace(src_sdk, dest_sdk)
        destdir = os.path.dirname(dst)
        mkdir(destdir)
        logger.debug("Copying %s to %s" % (sb, dst))
        shutil.copy(sb, dst)

def check_manifest(fn, basepath):
    import bb.utils
    changedfiles = []
    with open(fn, 'r') as f:
        for line in f:
            splitline = line.split()
            if len(splitline) > 1:
                chksum = splitline[0]
                fpath = splitline[1]
                curr_chksum = bb.utils.sha256_file(os.path.join(basepath, fpath))
                if chksum != curr_chksum:
                    logger.debug('File %s changed: old csum = %s, new = %s' % (os.path.join(basepath, fpath), curr_chksum, chksum))
                    changedfiles.append(fpath)
    return changedfiles

def sdk_update(args, config, basepath, workspace):
    """Entry point for devtool sdk-update command"""
    updateserver = args.updateserver
    if not updateserver:
        updateserver = config.get('SDK', 'updateserver', '')
    logger.debug("updateserver: %s" % updateserver)

    # Make sure we are using sdk-update from within SDK
    logger.debug("basepath = %s" % basepath)
    old_locked_sig_file_path = os.path.join(basepath, 'conf/locked-sigs.inc')
    if not os.path.exists(old_locked_sig_file_path):
        logger.error("Not using devtool's sdk-update command from within an extensible SDK. Please specify correct basepath via --basepath option")
        return -1
    else:
        logger.debug("Found conf/locked-sigs.inc in %s" % basepath)

    if not '://' in updateserver:
        logger.error("Update server must be a URL")
        return -1

    layers_dir = os.path.join(basepath, 'layers')
    conf_dir = os.path.join(basepath, 'conf')

    # Grab variable values
    tinfoil = setup_tinfoil(config_only=True, basepath=basepath)
    try:
        stamps_dir = tinfoil.config_data.getVar('STAMPS_DIR')
        sstate_mirrors = tinfoil.config_data.getVar('SSTATE_MIRRORS')
        site_conf_version = tinfoil.config_data.getVar('SITE_CONF_VERSION')
    finally:
        tinfoil.shutdown()

    tmpsdk_dir = tempfile.mkdtemp()
    try:
        os.makedirs(os.path.join(tmpsdk_dir, 'conf'))
        new_locked_sig_file_path = os.path.join(tmpsdk_dir, 'conf', 'locked-sigs.inc')
        # Fetch manifest from server
        tmpmanifest = os.path.join(tmpsdk_dir, 'conf', 'sdk-conf-manifest')
        ret = subprocess.call("wget -q -O %s %s/conf/sdk-conf-manifest" % (tmpmanifest, updateserver), shell=True)
        if ret != 0:
            logger.error("Cannot dowload files from %s" % updateserver)
            return ret
        changedfiles = check_manifest(tmpmanifest, basepath)
        if not changedfiles:
            logger.info("Already up-to-date")
            return 0
        # Update metadata
        logger.debug("Updating metadata via git ...")
        #Check for the status before doing a fetch and reset
        if os.path.exists(os.path.join(basepath, 'layers/.git')):
            out = subprocess.check_output("git status --porcelain", shell=True, cwd=layers_dir)
            if not out:
                ret = subprocess.call("git fetch --all; git reset --hard @{u}", shell=True, cwd=layers_dir)
            else:
                logger.error("Failed to update metadata as there have been changes made to it. Aborting.");
                logger.error("Changed files:\n%s" % out);
                return -1
        else:
            ret = -1
        if ret != 0:
            ret = subprocess.call("git clone %s/layers/.git" % updateserver, shell=True, cwd=tmpsdk_dir)
            if ret != 0:
                logger.error("Updating metadata via git failed")
                return ret
        logger.debug("Updating conf files ...")
        for changedfile in changedfiles:
            ret = subprocess.call("wget -q -O %s %s/%s" % (changedfile, updateserver, changedfile), shell=True, cwd=tmpsdk_dir)
            if ret != 0:
                logger.error("Updating %s failed" % changedfile)
                return ret

        # Check if UNINATIVE_CHECKSUM changed
        uninative = False
        if 'conf/local.conf' in changedfiles:
            def read_uninative_checksums(fn):
                chksumitems = []
                with open(fn, 'r') as f:
                    for line in f:
                        if line.startswith('UNINATIVE_CHECKSUM'):
                            splitline = re.split(r'[\[\]"\']', line)
                            if len(splitline) > 3:
                                chksumitems.append((splitline[1], splitline[3]))
                return chksumitems

            oldsums = read_uninative_checksums(os.path.join(basepath, 'conf/local.conf'))
            newsums = read_uninative_checksums(os.path.join(tmpsdk_dir, 'conf/local.conf'))
            if oldsums != newsums:
                uninative = True
                for buildarch, chksum in newsums:
                    uninative_file = os.path.join('downloads', 'uninative', chksum, '%s-nativesdk-libc.tar.bz2' % buildarch)
                    mkdir(os.path.join(tmpsdk_dir, os.path.dirname(uninative_file)))
                    ret = subprocess.call("wget -q -O %s %s/%s" % (uninative_file, updateserver, uninative_file), shell=True, cwd=tmpsdk_dir)

        # Ok, all is well at this point - move everything over
        tmplayers_dir = os.path.join(tmpsdk_dir, 'layers')
        if os.path.exists(tmplayers_dir):
            shutil.rmtree(layers_dir)
            shutil.move(tmplayers_dir, layers_dir)
        for changedfile in changedfiles:
            destfile = os.path.join(basepath, changedfile)
            os.remove(destfile)
            shutil.move(os.path.join(tmpsdk_dir, changedfile), destfile)
        os.remove(os.path.join(conf_dir, 'sdk-conf-manifest'))
        shutil.move(tmpmanifest, conf_dir)
        if uninative:
            shutil.rmtree(os.path.join(basepath, 'downloads', 'uninative'))
            shutil.move(os.path.join(tmpsdk_dir, 'downloads', 'uninative'), os.path.join(basepath, 'downloads'))

        if not sstate_mirrors:
            with open(os.path.join(conf_dir, 'site.conf'), 'a') as f:
                f.write('SCONF_VERSION = "%s"\n' % site_conf_version)
                f.write('SSTATE_MIRRORS:append = " file://.* %s/sstate-cache/PATH"\n' % updateserver)
    finally:
        shutil.rmtree(tmpsdk_dir)

    if not args.skip_prepare:
        # Find all potentially updateable tasks
        sdk_update_targets = []
        tasks = ['do_populate_sysroot', 'do_packagedata']
        for root, _, files in os.walk(stamps_dir):
            for fn in files:
                if not '.sigdata.' in fn:
                    for task in tasks:
                        if '.%s.' % task in fn or '.%s_setscene.' % task in fn:
                            sdk_update_targets.append('%s:%s' % (os.path.basename(root), task))
        # Run bitbake command for the whole SDK
        logger.info("Preparing build system... (This may take some time.)")
        try:
            exec_build_env_command(config.init_path, basepath, 'bitbake --setscene-only %s' % ' '.join(sdk_update_targets), stderr=subprocess.STDOUT)
            output, _ = exec_build_env_command(config.init_path, basepath, 'bitbake -n %s' % ' '.join(sdk_update_targets), stderr=subprocess.STDOUT)
            runlines = []
            for line in output.splitlines():
                if 'Running task ' in line:
                    runlines.append(line)
            if runlines:
                logger.error('Unexecuted tasks found in preparation log:\n  %s' % '\n  '.join(runlines))
                return -1
        except bb.process.ExecutionError as e:
            logger.error('Preparation failed:\n%s' % e.stdout)
            return -1
    return 0

def sdk_install(args, config, basepath, workspace):
    """Entry point for the devtool sdk-install command"""

    import oe.recipeutils
    import bb.process

    for recipe in args.recipename:
        if recipe in workspace:
            raise DevtoolError('recipe %s is a recipe in your workspace' % recipe)

    tasks = ['do_populate_sysroot', 'do_packagedata']
    stampprefixes = {}
    def checkstamp(recipe):
        stampprefix = stampprefixes[recipe]
        stamps = glob.glob(stampprefix + '*')
        for stamp in stamps:
            if '.sigdata.' not in stamp and stamp.startswith((stampprefix + '.', stampprefix + '_setscene.')):
                return True
        else:
            return False

    install_recipes = []
    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
    try:
        for recipe in args.recipename:
            rd = parse_recipe(config, tinfoil, recipe, True)
            if not rd:
                return 1
            stampprefixes[recipe] = '%s.%s' % (rd.getVar('STAMP'), tasks[0])
            if checkstamp(recipe):
                logger.info('%s is already installed' % recipe)
            else:
                install_recipes.append(recipe)
    finally:
        tinfoil.shutdown()

    if install_recipes:
        logger.info('Installing %s...' % ', '.join(install_recipes))
        install_tasks = []
        for recipe in install_recipes:
            for task in tasks:
                if recipe.endswith('-native') and 'package' in task:
                    continue
                install_tasks.append('%s:%s' % (recipe, task))
        options = ''
        if not args.allow_build:
            options += ' --setscene-only'
        try:
            exec_build_env_command(config.init_path, basepath, 'bitbake %s %s' % (options, ' '.join(install_tasks)), watch=True)
        except bb.process.ExecutionError as e:
            raise DevtoolError('Failed to install %s:\n%s' % (recipe, str(e)))
        failed = False
        for recipe in install_recipes:
            if checkstamp(recipe):
                logger.info('Successfully installed %s' % recipe)
            else:
                raise DevtoolError('Failed to install %s - unavailable' % recipe)
                failed = True
        if failed:
            return 2

        try:
            exec_build_env_command(config.init_path, basepath, 'bitbake build-sysroots', watch=True)
        except bb.process.ExecutionError as e:
            raise DevtoolError('Failed to bitbake build-sysroots:\n%s' % (str(e)))


def register_commands(subparsers, context):
    """Register devtool subcommands from the sdk plugin"""
    if context.fixed_setup:
        parser_sdk = subparsers.add_parser('sdk-update',
                                           help='Update SDK components',
                                           description='Updates installed SDK components from a remote server',
                                           group='sdk')
        updateserver = context.config.get('SDK', 'updateserver', '')
        if updateserver:
            parser_sdk.add_argument('updateserver', help='The update server to fetch latest SDK components from (default %s)' % updateserver, nargs='?')
        else:
            parser_sdk.add_argument('updateserver', help='The update server to fetch latest SDK components from')
        parser_sdk.add_argument('--skip-prepare', action="store_true", help='Skip re-preparing the build system after updating (for debugging only)')
        parser_sdk.set_defaults(func=sdk_update)

        parser_sdk_install = subparsers.add_parser('sdk-install',
                                                   help='Install additional SDK components',
                                                   description='Installs additional recipe development files into the SDK. (You can use "devtool search" to find available recipes.)',
                                                   group='sdk')
        parser_sdk_install.add_argument('recipename', help='Name of the recipe to install the development artifacts for', nargs='+')
        parser_sdk_install.add_argument('-s', '--allow-build', help='Allow building requested item(s) from source', action='store_true')
        parser_sdk_install.set_defaults(func=sdk_install)
