#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

# Development tool - source extraction helper class
#
# NOTE: this class is intended for use by devtool and should not be
# inherited manually.
#
# Copyright (C) 2014-2017 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.


DEVTOOL_TEMPDIR ?= ""
DEVTOOL_PATCH_SRCDIR = "${DEVTOOL_TEMPDIR}/patchworkdir"


python() {
    tempdir = d.getVar('DEVTOOL_TEMPDIR')

    if not tempdir:
        bb.fatal('devtool-source class is for internal use by devtool only')

    # Make a subdir so we guard against WORKDIR==S
    workdir = os.path.join(tempdir, 'workdir')
    d.setVar('WORKDIR', workdir)
    if not d.getVar('S').startswith(workdir):
        # Usually a shared workdir recipe (kernel, gcc)
        # Try to set a reasonable default
        if bb.data.inherits_class('kernel', d):
            d.setVar('S', '${WORKDIR}/source')
        else:
            d.setVar('S', '${WORKDIR}/%s' % os.path.basename(d.getVar('S')))
    if bb.data.inherits_class('kernel', d):
        # We don't want to move the source to STAGING_KERNEL_DIR here
        d.setVar('STAGING_KERNEL_DIR', '${S}')

    d.setVar('STAMPS_DIR', os.path.join(tempdir, 'stamps'))
    d.setVar('T', os.path.join(tempdir, 'temp'))

    # Hook in pre/postfuncs
    is_kernel_yocto = bb.data.inherits_class('kernel-yocto', d)
    if is_kernel_yocto:
        unpacktask = 'do_kernel_checkout'
        d.appendVarFlag('do_configure', 'postfuncs', ' devtool_post_configure')
    else:
        unpacktask = 'do_unpack'
    d.appendVarFlag(unpacktask, 'postfuncs', ' devtool_post_unpack')
    d.prependVarFlag('do_patch', 'prefuncs', ' devtool_pre_patch')
    d.appendVarFlag('do_patch', 'postfuncs', ' devtool_post_patch')

    # NOTE: in order for the patch stuff to be fully functional,
    # PATCHTOOL and PATCH_COMMIT_FUNCTIONS need to be set; we can't
    # do that here because we can't guarantee the order of the anonymous
    # functions, so it gets done in the bbappend we create.
}


python devtool_post_unpack() {
    import oe.recipeutils
    import shutil
    sys.path.insert(0, os.path.join(d.getVar('COREBASE'), 'scripts', 'lib'))
    import scriptutils
    from devtool import setup_git_repo

    tempdir = d.getVar('DEVTOOL_TEMPDIR')
    workdir = d.getVar('WORKDIR')
    srcsubdir = d.getVar('S')

    def _move_file(src, dst):
        """Move a file. Creates all the directory components of destination path."""
        dst_d = os.path.dirname(dst)
        if dst_d:
            bb.utils.mkdirhier(dst_d)
        shutil.move(src, dst)

    def _ls_tree(directory):
        """Recursive listing of files in a directory"""
        ret = []
        for root, dirs, files in os.walk(directory):
            ret.extend([os.path.relpath(os.path.join(root, fname), directory) for
                        fname in files])
        return ret

    is_kernel_yocto = bb.data.inherits_class('kernel-yocto', d)
    # Move local source files into separate subdir
    recipe_patches = [os.path.basename(patch) for patch in
                        oe.recipeutils.get_recipe_patches(d)]
    local_files = oe.recipeutils.get_recipe_local_files(d)

    if is_kernel_yocto:
        for key in [f for f in local_files if f.endswith('scc')]:
            with open(local_files[key], 'r') as sccfile:
                for l in sccfile:
                    line = l.split()
                    if line and line[0] in ('kconf', 'patch'):
                        cfg = os.path.join(os.path.dirname(local_files[key]), line[-1])
                        if cfg not in local_files.values():
                            local_files[line[-1]] = cfg
                            shutil.copy2(cfg, workdir)

    # Ignore local files with subdir={BP}
    srcabspath = os.path.abspath(srcsubdir)
    local_files = [fname for fname in local_files if
                    os.path.exists(os.path.join(workdir, fname)) and
                    (srcabspath == workdir or not
                    os.path.join(workdir, fname).startswith(srcabspath +
                        os.sep))]
    if local_files:
        for fname in local_files:
            _move_file(os.path.join(workdir, fname),
                        os.path.join(tempdir, 'oe-local-files', fname))
        with open(os.path.join(tempdir, 'oe-local-files', '.gitignore'),
                    'w') as f:
            f.write('# Ignore local files, by default. Remove this file '
                    'if you want to commit the directory to Git\n*\n')

    if srcsubdir == workdir:
        # Find non-patch non-local sources that were "unpacked" to srctree
        # directory
        src_files = [fname for fname in _ls_tree(workdir) if
                        os.path.basename(fname) not in recipe_patches]
        srcsubdir = d.getVar('DEVTOOL_PATCH_SRCDIR')
        # Move source files to S
        for path in src_files:
            _move_file(os.path.join(workdir, path),
                        os.path.join(srcsubdir, path))
    elif os.path.dirname(srcsubdir) != workdir:
        # Handle if S is set to a subdirectory of the source
        srcsubdir = os.path.join(workdir, os.path.relpath(srcsubdir, workdir).split(os.sep)[0])

    scriptutils.git_convert_standalone_clone(srcsubdir)

    # Make sure that srcsubdir exists
    bb.utils.mkdirhier(srcsubdir)
    if not os.listdir(srcsubdir):
        bb.warn("No source unpacked to S - either the %s recipe "
                "doesn't use any source or the correct source "
                "directory could not be determined" % d.getVar('PN'))

    devbranch = d.getVar('DEVTOOL_DEVBRANCH')
    setup_git_repo(srcsubdir, d.getVar('PV'), devbranch, d=d)

    (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srcsubdir)
    initial_rev = stdout.rstrip()
    with open(os.path.join(tempdir, 'initial_rev'), 'w') as f:
        f.write(initial_rev)

    with open(os.path.join(tempdir, 'srcsubdir'), 'w') as f:
        f.write(srcsubdir)
}

python devtool_pre_patch() {
    if d.getVar('S') == d.getVar('WORKDIR'):
        d.setVar('S', '${DEVTOOL_PATCH_SRCDIR}')
}

python devtool_post_patch() {
    import shutil
    tempdir = d.getVar('DEVTOOL_TEMPDIR')
    with open(os.path.join(tempdir, 'srcsubdir'), 'r') as f:
        srcsubdir = f.read()
    with open(os.path.join(tempdir, 'initial_rev'), 'r') as f:
        initial_rev = f.read()

    def rm_patches():
        patches_dir = os.path.join(srcsubdir, 'patches')
        if os.path.exists(patches_dir):
            shutil.rmtree(patches_dir)
        # Restore any "patches" directory that was actually part of the source tree
        try:
            bb.process.run('git checkout -- patches', cwd=srcsubdir)
        except bb.process.ExecutionError:
            pass

    extra_overrides = d.getVar('DEVTOOL_EXTRA_OVERRIDES')
    if extra_overrides:
        extra_overrides = set(extra_overrides.split(':'))
        devbranch = d.getVar('DEVTOOL_DEVBRANCH')
        default_overrides = d.getVar('OVERRIDES').split(':')
        no_overrides = []
        # First, we may have some overrides that are referred to in the recipe set in
        # our configuration, so we need to make a branch that excludes those
        for override in default_overrides:
            if override not in extra_overrides:
                no_overrides.append(override)
        if default_overrides != no_overrides:
            # Some overrides are active in the current configuration, so
            # we need to create a branch where none of the overrides are active
            bb.process.run('git checkout %s -b devtool-no-overrides' % initial_rev, cwd=srcsubdir)
            # Run do_patch function with the override applied
            localdata = bb.data.createCopy(d)
            localdata.setVar('OVERRIDES', ':'.join(no_overrides))
            localdata.setVar('FILESOVERRIDES', ':'.join(no_overrides))
            bb.build.exec_func('do_patch', localdata)
            rm_patches()
            # Now we need to reconcile the dev branch with the no-overrides one
            # (otherwise we'd likely be left with identical commits that have different hashes)
            bb.process.run('git checkout %s' % devbranch, cwd=srcsubdir)
            bb.process.run('git rebase devtool-no-overrides', cwd=srcsubdir)
        else:
            bb.process.run('git checkout %s -b devtool-no-overrides' % devbranch, cwd=srcsubdir)

        for override in extra_overrides:
            localdata = bb.data.createCopy(d)
            if override in default_overrides:
                bb.process.run('git branch devtool-override-%s %s' % (override, devbranch), cwd=srcsubdir)
            else:
                # Reset back to the initial commit on a new branch
                bb.process.run('git checkout %s -b devtool-override-%s' % (initial_rev, override), cwd=srcsubdir)
                # Run do_patch function with the override applied
                localdata.setVar('OVERRIDES', ':'.join(no_overrides + [override]))
                localdata.setVar('FILESOVERRIDES', ':'.join(no_overrides + [override]))
                bb.build.exec_func('do_patch', localdata)
                rm_patches()
                # Now we need to reconcile the new branch with the no-overrides one
                # (otherwise we'd likely be left with identical commits that have different hashes)
                bb.process.run('git rebase devtool-no-overrides', cwd=srcsubdir)
        bb.process.run('git checkout %s' % devbranch, cwd=srcsubdir)
    bb.process.run('git tag -f devtool-patched', cwd=srcsubdir)
}

python devtool_post_configure() {
    import shutil
    tempdir = d.getVar('DEVTOOL_TEMPDIR')
    shutil.copy2(os.path.join(d.getVar('B'), '.config'), tempdir)
}
