#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright 2011 Intel Corporation
# Authored-by:  Yu Ke <ke.yu@intel.com>
#               Paul Eggleton <paul.eggleton@intel.com>
#               Richard Purdie <richard.purdie@intel.com>
#
# 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 fnmatch
import os, sys
import optparse
import logging
import subprocess
import tempfile
import ConfigParser
import re
from collections import OrderedDict
from string import Template

__version__ = "0.2.1"

def logger_create():
    logger = logging.getLogger("")
    loggerhandler = logging.StreamHandler()
    loggerhandler.setFormatter(logging.Formatter("[%(asctime)s] %(message)s","%H:%M:%S"))
    logger.addHandler(loggerhandler)
    logger.setLevel(logging.INFO)
    return logger

logger = logger_create()

def get_current_branch(repodir=None):
    try:
        if not os.path.exists(os.path.join(repodir if repodir else '', ".git")):
            # Repo not created yet (i.e. during init) so just assume master
            return "master"
        branchname = runcmd("git symbolic-ref HEAD 2>/dev/null", repodir).strip()
        if branchname.startswith("refs/heads/"):
            branchname = branchname[11:]
        return branchname
    except subprocess.CalledProcessError:
        return ""

class Configuration(object):
    """
    Manages the configuration

    For an example config file, see combo-layer.conf.example

    """
    def __init__(self, options):
        for key, val in options.__dict__.items():
            setattr(self, key, val)

        def readsection(parser, section, repo):
            for (name, value) in parser.items(section):
                if value.startswith("@"):
                    self.repos[repo][name] = eval(value.strip("@"))
                else:
                    # Apply special type transformations for some properties.
                    # Type matches the RawConfigParser.get*() methods.
                    types = {'signoff': 'boolean', 'update': 'boolean'}
                    if name in types:
                        value = getattr(parser, 'get' + types[name])(section, name)
                    self.repos[repo][name] = value

        def readglobalsection(parser, section):
            for (name, value) in parser.items(section):
                if name == "commit_msg":
                    self.commit_msg_template = value

        logger.debug("Loading config file %s" % self.conffile)
        self.parser = ConfigParser.ConfigParser()
        with open(self.conffile) as f:
            self.parser.readfp(f)

        # initialize default values
        self.commit_msg_template = "Automatic commit to update last_revision"

        self.repos = {}
        for repo in self.parser.sections():
            if repo == "combo-layer-settings":
                # special handling for global settings
                readglobalsection(self.parser, repo)
            else:
                self.repos[repo] = {}
                readsection(self.parser, repo, repo)

        # Load local configuration, if available
        self.localconffile = None
        self.localparser = None
        self.combobranch = None
        if self.conffile.endswith('.conf'):
            lcfile = self.conffile.replace('.conf', '-local.conf')
            if os.path.exists(lcfile):
                # Read combo layer branch
                self.combobranch = get_current_branch()
                logger.debug("Combo layer branch is %s" % self.combobranch)

                self.localconffile = lcfile
                logger.debug("Loading local config file %s" % self.localconffile)
                self.localparser = ConfigParser.ConfigParser()
                with open(self.localconffile) as f:
                    self.localparser.readfp(f)

                for section in self.localparser.sections():
                    if '|' in section:
                        sectionvals = section.split('|')
                        repo = sectionvals[0]
                        if sectionvals[1] != self.combobranch:
                            continue
                    else:
                        repo = section
                    if repo in self.repos:
                        readsection(self.localparser, section, repo)

    def update(self, repo, option, value, initmode=False):
        # If the main config has the option already, that is what we
        # are expected to modify.
        if self.localparser and not self.parser.has_option(repo, option):
            parser = self.localparser
            section = "%s|%s" % (repo, self.combobranch)
            conffile = self.localconffile
            if initmode and not parser.has_section(section):
                parser.add_section(section)
        else:
            parser = self.parser
            section = repo
            conffile = self.conffile
        parser.set(section, option, value)
        with open(conffile, "w") as f:
            parser.write(f)
        self.repos[repo][option] = value

    def sanity_check(self, initmode=False):
        required_options=["src_uri", "local_repo_dir", "dest_dir", "last_revision"]
        if initmode:
            required_options.remove("last_revision")
        msg = ""
        missing_options = []
        for name in self.repos:
            for option in required_options:
                if option not in self.repos[name]:
                    msg = "%s\nOption %s is not defined for component %s" %(msg, option, name)
                    missing_options.append(option)
            # Sanitize dest_dir so that we do not have to deal with edge cases
            # (unset, empty string, double slashes) in the rest of the code.
            # It not being set will still be flagged as error because it is
            # listed as required option above; that could be changed now.
            dest_dir = os.path.normpath(self.repos[name].get("dest_dir", "."))
            self.repos[name]["dest_dir"] = "." if not dest_dir else dest_dir
        if msg != "":
            logger.error("configuration file %s has the following error: %s" % (self.conffile,msg))
            if self.localconffile and 'last_revision' in missing_options:
                logger.error("local configuration file %s may be missing configuration for combo branch %s" % (self.localconffile, self.combobranch))
            sys.exit(1)

        # filterdiff is required by action_splitpatch, so check its availability
        if subprocess.call("which filterdiff > /dev/null 2>&1", shell=True) != 0:
            logger.error("ERROR: patchutils package is missing, please install it (e.g. # apt-get install patchutils)")
            sys.exit(1)

def runcmd(cmd,destdir=None,printerr=True,out=None):
    """
        execute command, raise CalledProcessError if fail
        return output if succeed
    """
    logger.debug("run cmd '%s' in %s" % (cmd, os.getcwd() if destdir is None else destdir))
    if not out:
        out = os.tmpfile()
        err = out
    else:
        err = os.tmpfile()
    try:
        subprocess.check_call(cmd, stdout=out, stderr=err, cwd=destdir, shell=isinstance(cmd, str))
    except subprocess.CalledProcessError,e:
        err.seek(0)
        if printerr:
            logger.error("%s" % err.read())
        raise e

    err.seek(0)
    output = err.read()
    logger.debug("output: %s" % output )
    return output

def action_init(conf, args):
    """
        Clone component repositories
        Check git is initialised; if not, copy initial data from component repos
    """
    for name in conf.repos:
        ldir = conf.repos[name]['local_repo_dir']
        if not os.path.exists(ldir):
            logger.info("cloning %s to %s" %(conf.repos[name]['src_uri'], ldir))
            subprocess.check_call("git clone %s %s" % (conf.repos[name]['src_uri'], ldir), shell=True)
    if not os.path.exists(".git"):
        runcmd("git init")
        if conf.history:
            # Need a common ref for all trees.
            runcmd('git commit -m "initial empty commit" --allow-empty')
            startrev = runcmd('git rev-parse master').strip()

        for name in conf.repos:
            repo = conf.repos[name]
            ldir = repo['local_repo_dir']
            branch = repo.get('branch', "master")
            lastrev = repo.get('last_revision', None)
            if lastrev and lastrev != "HEAD":
                initialrev = lastrev
                if branch:
                    if not check_rev_branch(name, ldir, lastrev, branch):
                        sys.exit(1)
                logger.info("Copying data from %s at specified revision %s..." % (name, lastrev))
            else:
                lastrev = None
                initialrev = branch
                logger.info("Copying data from %s..." % name)
            # Sanity check initialrev and turn it into hash (required for copying history,
            # because resolving a name ref only works in the component repo).
            rev = runcmd('git rev-parse %s' % initialrev, ldir).strip()
            if rev != initialrev:
                try:
                    refs = runcmd('git show-ref -s %s' % initialrev, ldir).split('\n')
                    if len(set(refs)) > 1:
                        # Happens for example when configured to track
                        # "master" and there is a refs/heads/master. The
                        # traditional behavior from "git archive" (preserved
                        # here) it to choose the first one. This might not be
                        # intended, so at least warn about it.
                        logger.warn("%s: initial revision '%s' not unique, picking result of rev-parse = %s" %
                                    (name, initialrev, refs[0]))
                        initialrev = rev
                except:
                    # show-ref fails for hashes. Skip the sanity warning in that case.
                    pass
                initialrev = rev
            dest_dir = repo['dest_dir']
            if dest_dir != ".":
                extract_dir = os.path.join(os.getcwd(), dest_dir)
                if not os.path.exists(extract_dir):
                    os.makedirs(extract_dir)
            else:
                extract_dir = os.getcwd()
            file_filter = repo.get('file_filter', "")
            exclude_patterns = repo.get('file_exclude', '').split()
            def copy_selected_files(initialrev, extract_dir, file_filter, exclude_patterns, ldir,
                                    subdir=""):
                # When working inside a filtered branch which had the
                # files already moved, we need to prepend the
                # subdirectory to all filters, otherwise they would
                # not match.
                if subdir == '.':
                    subdir = ''
                elif subdir:
                    subdir = os.path.normpath(subdir)
                    file_filter = ' '.join([subdir + '/' + x for x in file_filter.split()])
                    exclude_patterns = [subdir + '/' + x for x in exclude_patterns]
                # To handle both cases, we cd into the target
                # directory and optionally tell tar to strip the path
                # prefix when the files were already moved.
                subdir_components = len(subdir.split(os.path.sep)) if subdir else 0
                strip=('--strip-components=%d' % subdir_components) if subdir else ''
                # TODO: file_filter wild cards do not work (and haven't worked before either), because
                # a) GNU tar requires a --wildcards parameter before turning on wild card matching.
                # b) The semantic is not as intendend (src/*.c also matches src/foo/bar.c,
                #    in contrast to the other use of file_filter as parameter of "git archive"
                #    where it only matches .c files directly in src).
                files = runcmd("git archive %s %s | tar -x -v %s -C %s %s" %
                               (initialrev, subdir,
                                strip, extract_dir, file_filter),
                               ldir)
                if exclude_patterns:
                    # Implement file removal by letting tar create the
                    # file and then deleting it in the file system
                    # again. Uses the list of files created by tar (easier
                    # than walking the tree).
                    for file in files.split('\n'):
                        for pattern in exclude_patterns:
                            if fnmatch.fnmatch(file, pattern):
                                os.unlink(os.path.join(*([extract_dir] + ['..'] * subdir_components + [file])))
                                break

            if not conf.history:
                copy_selected_files(initialrev, extract_dir, file_filter, exclude_patterns, ldir)
            else:
                # First fetch remote history into local repository.
                # We need a ref for that, so ensure that there is one.
                refname = "combo-layer-init-%s" % name
                runcmd("git branch -f %s %s" % (refname, initialrev), ldir)
                runcmd("git fetch %s %s" % (ldir, refname))
                runcmd("git branch -D %s" % refname, ldir)
                # Make that the head revision.
                runcmd("git checkout -b %s %s" % (name, initialrev))
                # Optional: cut the history by replacing the given
                # start point(s) with commits providing the same
                # content (aka tree), but with commit information that
                # makes it clear that this is an artifically created
                # commit and nothing the original authors had anything
                # to do with.
                since_rev = repo.get('since_revision', '')
                if since_rev:
                    committer = runcmd('git var GIT_AUTHOR_IDENT').strip()
                    # Same time stamp, no name.
                    author = re.sub('.* (\d+ [+-]\d+)', r'unknown <unknown> \1', committer)
                    logger.info('author %s' % author)
                    for rev in since_rev.split():
                        # Resolve in component repo...
                        rev = runcmd('git log --oneline --no-abbrev-commit -n1 %s' % rev, ldir).split()[0]
                        # ... and then get the tree in current
                        # one. The commit should be in both repos with
                        # the same tree, but better check here.
                        tree = runcmd('git show -s --pretty=format:%%T %s' % rev).strip()
                        with tempfile.NamedTemporaryFile() as editor:
                            editor.write('''cat >$1 <<EOF
tree %s
author %s
committer %s

%s: squashed import of component

This commit copies the entire set of files as found in
%s %s

For more information about previous commits, see the
upstream repository.

Commit created by combo-layer.
EOF
''' % (tree, author, committer, name, name, since_rev))
                            editor.flush()
                            os.environ['GIT_EDITOR'] = 'sh %s' % editor.name
                            runcmd('git replace --edit %s' % rev)

                # Optional: rewrite history to change commit messages or to move files.
                if 'hook' in repo or dest_dir != ".":
                    filter_branch = ['git', 'filter-branch', '--force']
                    with tempfile.NamedTemporaryFile() as hookwrapper:
                        if 'hook' in repo:
                            # Create a shell script wrapper around the original hook that
                            # can be used by git filter-branch. Hook may or may not have
                            # an absolute path.
                            hook = repo['hook']
                            hook = os.path.join(os.path.dirname(conf.conffile), '..', hook)
                            # The wrappers turns the commit message
                            # from stdin into a fake patch header.
                            # This is good enough for changing Subject
                            # and commit msg body with normal
                            # combo-layer hooks.
                            hookwrapper.write('''set -e
tmpname=$(mktemp)
trap "rm $tmpname" EXIT
echo -n 'Subject: [PATCH] ' >>$tmpname
cat >>$tmpname
if ! [ $(tail -c 1 $tmpname | od -A n -t x1) == '0a' ]; then
    echo >>$tmpname
fi
echo '---' >>$tmpname
%s $tmpname $GIT_COMMIT %s
tail -c +18 $tmpname | head -c -4
''' % (hook, name))
                            hookwrapper.flush()
                            filter_branch.extend(['--msg-filter', 'bash %s' % hookwrapper.name])
                        if dest_dir != ".":
                            parent = os.path.dirname(dest_dir)
                            if not parent:
                                parent = '.'
                            # May run outside of the current directory, so do not assume that .git exists.
                            filter_branch.extend(['--tree-filter', 'mkdir -p .git/tmptree && find . -mindepth 1 -maxdepth 1 ! -name .git -print0 | xargs -0 -I SOURCE mv SOURCE .git/tmptree && mkdir -p %s && mv .git/tmptree %s' % (parent, dest_dir)])
                        filter_branch.append('HEAD')
                        runcmd(filter_branch)
                        runcmd('git update-ref -d refs/original/refs/heads/%s' % name)
                repo['rewritten_revision'] = runcmd('git rev-parse HEAD').strip()
                repo['stripped_revision'] = repo['rewritten_revision']
                # Optional filter files: remove everything and re-populate using the normal filtering code.
                # Override any potential .gitignore.
                if file_filter or exclude_patterns:
                    runcmd('git rm -rf .')
                    if not os.path.exists(extract_dir):
                        os.makedirs(extract_dir)
                    copy_selected_files('HEAD', extract_dir, file_filter, exclude_patterns, '.',
                                        subdir=dest_dir)
                    runcmd('git add --all --force .')
                    if runcmd('git status --porcelain'):
                        # Something to commit.
                        runcmd(['git', 'commit', '-m',
                                '''%s: select file subset

Files from the component repository were chosen based on
the following filters:
file_filter = %s
file_exclude = %s''' % (name, file_filter or '<empty>', repo.get('file_exclude', '<empty>'))])
                        repo['stripped_revision'] = runcmd('git rev-parse HEAD').strip()

            if not lastrev:
                lastrev = runcmd('git rev-parse %s' % initialrev, ldir).strip()
                conf.update(name, "last_revision", lastrev, initmode=True)

        if not conf.history:
            runcmd("git add .")
        else:
            # Create Octopus merge commit according to http://stackoverflow.com/questions/10874149/git-octopus-merge-with-unrelated-repositoies
            runcmd('git checkout master')
            merge = ['git', 'merge', '--no-commit']
            for name in conf.repos:
                repo = conf.repos[name]
                # Use branch created earlier.
                merge.append(name)
                # Root all commits which have no parent in the common
                # ancestor in the new repository.
                for start in runcmd('git log --pretty=format:%%H --max-parents=0 %s' % name).split('\n'):
                    runcmd('git replace --graft %s %s' % (start, startrev))
            try:
                runcmd(merge)
            except Exception, error:
                logger.info('''Merging component repository history failed, perhaps because of merge conflicts.
It may be possible to commit anyway after resolving these conflicts.

%s''' % error)
            # Create MERGE_HEAD and MERGE_MSG. "git merge" itself
            # does not create MERGE_HEAD in case of a (harmless) failure,
            # and we want certain auto-generated information in the
            # commit message for future reference and/or automation.
            with open('.git/MERGE_HEAD', 'w') as head:
                with open('.git/MERGE_MSG', 'w') as msg:
                    msg.write('repo: initial import of components\n\n')
                    # head.write('%s\n' % startrev)
                    for name in conf.repos:
                        repo = conf.repos[name]
                        # <upstream ref> <rewritten ref> <rewritten + files removed>
                        msg.write('combo-layer-%s: %s %s %s\n' % (name,
                                                                  repo['last_revision'],
                                                                  repo['rewritten_revision'],
                                                                  repo['stripped_revision']))
                        rev = runcmd('git rev-parse %s' % name).strip()
                        head.write('%s\n' % rev)

        if conf.localconffile:
            localadded = True
            try:
                runcmd("git rm --cached %s" % conf.localconffile, printerr=False)
            except subprocess.CalledProcessError:
                localadded = False
            if localadded:
                localrelpath = os.path.relpath(conf.localconffile)
                runcmd("grep -q %s .gitignore || echo %s >> .gitignore" % (localrelpath, localrelpath))
                runcmd("git add .gitignore")
                logger.info("Added local configuration file %s to .gitignore", localrelpath)
        logger.info("Initial combo layer repository data has been created; please make any changes if desired and then use 'git commit' to make the initial commit.")
    else:
        logger.info("Repository already initialised, nothing to do.")


def check_repo_clean(repodir):
    """
        check if the repo is clean
        exit if repo is dirty
    """
    output=runcmd("git status --porcelain", repodir)
    r = re.compile('\?\? patch-.*/')
    dirtyout = [item for item in output.splitlines() if not r.match(item)]
    if dirtyout:
        logger.error("git repo %s is dirty, please fix it first", repodir)
        sys.exit(1)

def check_patch(patchfile):
    f = open(patchfile)
    ln = f.readline()
    of = None
    in_patch = False
    beyond_msg = False
    pre_buf = ''
    while ln:
        if not beyond_msg:
            if ln == '---\n':
                if not of:
                    break
                in_patch = False
                beyond_msg = True
            elif ln.startswith('--- '):
                # We have a diff in the commit message
                in_patch = True
                if not of:
                    print('WARNING: %s contains a diff in its commit message, indenting to avoid failure during apply' % patchfile)
                    of = open(patchfile + '.tmp', 'w')
                    of.write(pre_buf)
                    pre_buf = ''
            elif in_patch and not ln[0] in '+-@ \n\r':
                in_patch = False
        if of:
            if in_patch:
                of.write(' ' + ln)
            else:
                of.write(ln)
        else:
            pre_buf += ln
        ln = f.readline()
    f.close()
    if of:
        of.close()
        os.rename(patchfile + '.tmp', patchfile)

def drop_to_shell(workdir=None):
    if not sys.stdin.isatty():
        print "Not a TTY so can't drop to shell for resolution, exiting."
        return False

    shell = os.environ.get('SHELL', 'bash')
    print('Dropping to shell "%s"\n' \
          'When you are finished, run the following to continue:\n' \
          '       exit    -- continue to apply the patches\n' \
          '       exit 1  -- abort\n' % shell);
    ret = subprocess.call([shell], cwd=workdir)
    if ret != 0:
        print "Aborting"
        return False
    else:
        return True

def check_rev_branch(component, repodir, rev, branch):
    try:
        actualbranch = runcmd("git branch --contains %s" % rev, repodir, printerr=False)
    except subprocess.CalledProcessError as e:
        if e.returncode == 129:
            actualbranch = ""
        else:
            raise

    if not actualbranch:
        logger.error("%s: specified revision %s is invalid!" % (component, rev))
        return False

    branches = []
    branchlist = actualbranch.split("\n")
    for b in branchlist:
        branches.append(b.strip().split(' ')[-1])

    if branch not in branches:
        logger.error("%s: specified revision %s is not on specified branch %s!" % (component, rev, branch))
        return False
    return True

def get_repos(conf, repo_names):
    repos = []
    for name in repo_names:
        if name.startswith('-'):
            break
        else:
            repos.append(name)
    for repo in repos:
        if not repo in conf.repos:
            logger.error("Specified component '%s' not found in configuration" % repo)
            sys.exit(1)

    if not repos:
        repos = [ repo for repo in conf.repos if conf.repos[repo].get("update", True) ]

    return repos

def action_pull(conf, args):
    """
        update the component repos only
    """
    repos = get_repos(conf, args[1:])

    # make sure all repos are clean
    for name in repos:
        check_repo_clean(conf.repos[name]['local_repo_dir'])

    for name in repos:
        repo = conf.repos[name]
        ldir = repo['local_repo_dir']
        branch = repo.get('branch', "master")
        logger.info("update branch %s of component repo %s in %s ..." % (branch, name, ldir))
        if not conf.hard_reset:
            # Try to pull only the configured branch. Beware that this may fail
            # when the branch is currently unknown (for example, after reconfiguring
            # combo-layer). In that case we need to fetch everything and try the check out
            # and pull again.
            try:
                runcmd("git checkout %s" % branch, ldir, printerr=False)
            except subprocess.CalledProcessError:
                output=runcmd("git fetch", ldir)
                logger.info(output)
                runcmd("git checkout %s" % branch, ldir)
                runcmd("git pull --ff-only", ldir)
            else:
                output=runcmd("git pull --ff-only", ldir)
                logger.info(output)
        else:
            output=runcmd("git fetch", ldir)
            logger.info(output)
            runcmd("git checkout %s" % branch, ldir)
            runcmd("git reset --hard FETCH_HEAD", ldir)

def action_update(conf, args):
    """
        update the component repos
        generate the patch list
        apply the generated patches
    """
    components = [arg.split(':')[0] for arg in args[1:]]
    revisions = {}
    for arg in args[1:]:
        if ':' in arg:
            a = arg.split(':', 1)
            revisions[a[0]] = a[1]
    repos = get_repos(conf, components)

    # make sure combo repo is clean
    check_repo_clean(os.getcwd())

    import uuid
    patch_dir = "patch-%s" % uuid.uuid4()
    if not os.path.exists(patch_dir):
        os.mkdir(patch_dir)

    # Step 1: update the component repos
    if conf.nopull:
        logger.info("Skipping pull (-n)")
    else:
        action_pull(conf, ['arg0'] + components)

    for name in repos:
        revision = revisions.get(name, None)
        repo = conf.repos[name]
        ldir = repo['local_repo_dir']
        dest_dir = repo['dest_dir']
        branch = repo.get('branch', "master")
        repo_patch_dir = os.path.join(os.getcwd(), patch_dir, name)

        # Step 2: generate the patch list and store to patch dir
        logger.info("Generating patches from %s..." % name)
        top_revision = revision or branch
        if not check_rev_branch(name, ldir, top_revision, branch):
            sys.exit(1)
        if dest_dir != ".":
            prefix = "--src-prefix=a/%s/ --dst-prefix=b/%s/" % (dest_dir, dest_dir)
        else:
            prefix = ""
        if repo['last_revision'] == "":
            logger.info("Warning: last_revision of component %s is not set, starting from the first commit" % name)
            patch_cmd_range = "--root %s" % top_revision
            rev_cmd_range = top_revision
        else:
            if not check_rev_branch(name, ldir, repo['last_revision'], branch):
                sys.exit(1)
            patch_cmd_range = "%s..%s" % (repo['last_revision'], top_revision)
            rev_cmd_range = patch_cmd_range

        file_filter = repo.get('file_filter',".")

        # Filter out unwanted files
        exclude = repo.get('file_exclude', '')
        if exclude:
            for path in exclude.split():
                p = "%s/%s" % (dest_dir, path) if dest_dir != '.' else path
                file_filter += " ':!%s'" % p

        patch_cmd = "git format-patch -N %s --output-directory %s %s -- %s" % \
            (prefix,repo_patch_dir, patch_cmd_range, file_filter)
        output = runcmd(patch_cmd, ldir)
        logger.debug("generated patch set:\n%s" % output)
        patchlist = output.splitlines()

        rev_cmd = "git rev-list --no-merges %s -- %s" % (rev_cmd_range, file_filter)
        revlist = runcmd(rev_cmd, ldir).splitlines()

        # Step 3: Call repo specific hook to adjust patch
        if 'hook' in repo:
            # hook parameter is: ./hook patchpath revision reponame
            count=len(revlist)-1
            for patch in patchlist:
                runcmd("%s %s %s %s" % (repo['hook'], patch, revlist[count], name))
                count=count-1

        # Step 4: write patch list and revision list to file, for user to edit later
        patchlist_file = os.path.join(os.getcwd(), patch_dir, "patchlist-%s" % name)
        repo['patchlist'] = patchlist_file
        f = open(patchlist_file, 'w')
        count=len(revlist)-1
        for patch in patchlist:
            f.write("%s %s\n" % (patch, revlist[count]))
            check_patch(os.path.join(patch_dir, patch))
            count=count-1
        f.close()

    # Step 5: invoke bash for user to edit patch and patch list
    if conf.interactive:
        print('You may now edit the patch and patch list in %s\n' \
              'For example, you can remove unwanted patch entries from patchlist-*, so that they will be not applied later' % patch_dir);
        if not drop_to_shell(patch_dir):
            sys.exit(1)

    # Step 6: apply the generated and revised patch
    apply_patchlist(conf, repos)
    runcmd("rm -rf %s" % patch_dir)

    # Step 7: commit the updated config file if it's being tracked
    relpath = os.path.relpath(conf.conffile)
    try:
        output = runcmd("git status --porcelain %s" % relpath, printerr=False)
    except:
        # Outside the repository
        output = None
    if output:
        logger.info("Committing updated configuration file")
        if output.lstrip().startswith("M"):

            # create the "components" string
            component_str = "all components"
            if len(components) > 0:
                # otherwise tell which components were actually changed
                component_str = ", ".join(components)

            # expand the template with known values
            template = Template(conf.commit_msg_template)
            raw_msg = template.substitute(components = component_str)

            # sanitize the string before using it in command line
            msg = raw_msg.replace('"', '\\"')

            runcmd('git commit -m "%s" %s' % (msg, relpath))

def apply_patchlist(conf, repos):
    """
        apply the generated patch list to combo repo
    """
    for name in repos:
        repo = conf.repos[name]
        lastrev = repo["last_revision"]
        prevrev = lastrev

        # Get non-blank lines from patch list file
        patchlist = []
        if os.path.exists(repo['patchlist']) or not conf.interactive:
            # Note: we want this to fail here if the file doesn't exist and we're not in
            # interactive mode since the file should exist in this case
            with open(repo['patchlist']) as f:
                for line in f:
                    line = line.rstrip()
                    if line:
                        patchlist.append(line)

        ldir = conf.repos[name]['local_repo_dir']
        branch = conf.repos[name].get('branch', "master")
        branchrev = runcmd("git rev-parse %s" % branch, ldir).strip()

        if patchlist:
            logger.info("Applying patches from %s..." % name)
            linecount = len(patchlist)
            i = 1
            for line in patchlist:
                patchfile = line.split()[0]
                lastrev = line.split()[1]
                patchdisp = os.path.relpath(patchfile)
                if os.path.getsize(patchfile) == 0:
                    logger.info("(skipping %d/%d %s - no changes)" % (i, linecount, patchdisp))
                else:
                    cmd = "git am --keep-cr %s-p1 %s" % ('-s ' if repo.get('signoff', True) else '', patchfile)
                    logger.info("Applying %d/%d: %s" % (i, linecount, patchdisp))
                    try:
                        runcmd(cmd)
                    except subprocess.CalledProcessError:
                        logger.info('Running "git am --abort" to cleanup repo')
                        runcmd("git am --abort")
                        logger.error('"%s" failed' % cmd)
                        logger.info("Please manually apply patch %s" % patchdisp)
                        logger.info("Note: if you exit and continue applying without manually applying the patch, it will be skipped")
                        if not drop_to_shell():
                            if prevrev != repo['last_revision']:
                                conf.update(name, "last_revision", prevrev)
                            sys.exit(1)
                prevrev = lastrev
                i += 1
            # Once all patches are applied, we should update
            # last_revision to the branch head instead of the last
            # applied patch. The two are not necessarily the same when
            # the last commit is a merge commit or when the patches at
            # the branch head were intentionally excluded.
            #
            # If we do not do that for a merge commit, the next
            # combo-layer run will only exclude patches reachable from
            # one of the merged branches and try to re-apply patches
            # from other branches even though they were already
            # copied.
            #
            # If patches were intentionally excluded, the next run will
            # present them again instead of skipping over them. This
            # may or may not be intended, so the code here is conservative
            # and only addresses the "head is merge commit" case.
            if lastrev != branchrev and \
               len(runcmd("git show --pretty=format:%%P --no-patch %s" % branch, ldir).split()) > 1:
                lastrev = branchrev
        else:
            logger.info("No patches to apply from %s" % name)
            lastrev = branchrev

        if lastrev != repo['last_revision']:
            conf.update(name, "last_revision", lastrev)

def action_splitpatch(conf, args):
    """
        generate the commit patch and
        split the patch per repo
    """
    logger.debug("action_splitpatch")
    if len(args) > 1:
        commit = args[1]
    else:
        commit = "HEAD"
    patchdir = "splitpatch-%s" % commit
    if not os.path.exists(patchdir):
        os.mkdir(patchdir)

    # filerange_root is for the repo whose dest_dir is root "."
    # and it should be specified by excluding all other repo dest dir
    # like "-x repo1 -x repo2 -x repo3 ..."
    filerange_root = ""
    for name in conf.repos:
        dest_dir = conf.repos[name]['dest_dir']
        if dest_dir != ".":
            filerange_root = '%s -x "%s/*"' % (filerange_root, dest_dir)

    for name in conf.repos:
        dest_dir = conf.repos[name]['dest_dir']
        patch_filename = "%s/%s.patch" % (patchdir, name)
        if dest_dir == ".":
            cmd = "git format-patch -n1 --stdout %s^..%s | filterdiff -p1 %s > %s" % (commit, commit, filerange_root, patch_filename)
        else:
            cmd = "git format-patch --no-prefix -n1 --stdout %s^..%s -- %s > %s" % (commit, commit, dest_dir, patch_filename)
        runcmd(cmd)
        # Detect empty patches (including those produced by filterdiff above
        # that contain only preamble text)
        if os.path.getsize(patch_filename) == 0 or runcmd("filterdiff %s" % patch_filename) == "":
            os.remove(patch_filename)
            logger.info("(skipping %s - no changes)", name)
        else:
            logger.info(patch_filename)

def action_error(conf, args):
    logger.info("invalid action %s" % args[0])

actions = {
    "init": action_init,
    "update": action_update,
    "pull": action_pull,
    "splitpatch": action_splitpatch,
}

def main():
    parser = optparse.OptionParser(
        version = "Combo Layer Repo Tool version %s" % __version__,
        usage = """%prog [options] action

Create and update a combination layer repository from multiple component repositories.

Action:
  init                 initialise the combo layer repo
  update [components]  get patches from component repos and apply them to the combo repo
  pull [components]    just pull component repos only
  splitpatch [commit]  generate commit patch and split per component, default commit is HEAD""")

    parser.add_option("-c", "--conf", help = "specify the config file (conf/combo-layer.conf is the default).",
               action = "store", dest = "conffile", default = "conf/combo-layer.conf")

    parser.add_option("-i", "--interactive", help = "interactive mode, user can edit the patch list and patches",
               action = "store_true", dest = "interactive", default = False)

    parser.add_option("-D", "--debug", help = "output debug information",
               action = "store_true", dest = "debug", default = False)

    parser.add_option("-n", "--no-pull", help = "skip pulling component repos during update",
               action = "store_true", dest = "nopull", default = False)

    parser.add_option("--hard-reset",
               help = "instead of pull do fetch and hard-reset in component repos",
               action = "store_true", dest = "hard_reset", default = False)

    parser.add_option("-H", "--history", help = "import full history of components during init",
                      action = "store_true", default = False)

    options, args = parser.parse_args(sys.argv)

    # Dispatch to action handler
    if len(args) == 1:
        logger.error("No action specified, exiting")
        parser.print_help()
    elif args[1] not in actions:
        logger.error("Unsupported action %s, exiting\n" % (args[1]))
        parser.print_help()
    elif not os.path.exists(options.conffile):
        logger.error("No valid config file, exiting\n")
        parser.print_help()
    else:
        if options.debug:
            logger.setLevel(logging.DEBUG)
        confdata = Configuration(options)
        initmode = (args[1] == 'init')
        confdata.sanity_check(initmode)
        actions.get(args[1], action_error)(confdata, args[1:])

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