#!/bin/sh
#
# Copyright (C) 2009,2016  Etersoft
# Copyright (C) 2009-2016  Vitaly Lipatov <lav@etersoft.ru>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

PROGDIR=$(dirname $0)
[ "$PROGDIR" = "." ] && PROGDIR=$(pwd)

. $PROGDIR/giter-common-functions

# Do cherry pick for all commit from git log in reverse order

if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
	echo "gpick - cherry pick all commits for git log file in reverse order"
	echo "Use: gpick [options] file.log|file1.patch... file2.patch..."
	echo "Options:"
	echo "     --skip      skip commit (patch)"
	echo "     --autoskip  skip failed commit (patches) automatically"
	echo "     --continue  continue after fix"
	echo "     --abandon   break the process"
	echo
	echo "Hit: you can get git log with $ git log command"
	exit
fi

GITROOT=$(get_root_git_dir)
[ -d "$GITROOT/.git" ] || fatal "Use me in git repo dir only"

GFILE="$GITROOT/.git/gpick.commits"
PFILE="$GITROOT/.git/gpick.patches"

drop_last_line()
{
        # TODO: do it better!
        grep -v "$(tail -n1 "$1")" "$1" >"$1.tmp"
        rm -f "$1" || fatal
        mv "$1.tmp" "$1" || fatal
}

# here we remove last line
done_commit()
{
        drop_last_line "$GFILE"
}

done_patch()
{
        drop_last_line "$PFILE"
}


get_commit()
{
        tail -n1 "$GFILE" || fatal
}

get_patch()
{
        tail -n1 "$PFILE" || fatal
}

is_patch()
{
        rhas "$1" "\.patch$"
}

# if are in cherry pick progress
if [ -s "$GFILE" ] ; then
        case "$1" in
          "--skip")
            commit=$(get_commit)
            docmd git reset
            echo "Skipping commit $commit"
            done_commit
            ;;
          "--autoskip")
            AUTOSKIP=1
            ;;
          "--abandon")
            docmd rm -f "$GFILE"
            ;;
          "--continue"|"")
            ;;
          *)
            fatal "We are in cherry pick progress on $(get_commit) commit. Do not use args or check $GFILE file."
        esac
# if are in patch progress
elif [ -s "$PFILE" ] ; then
        case "$1" in
          "--skip")
            patch=$(get_patch)
            docmd git am --skip
            echo "Skipping patch $patch"
            done_patch
            ;;
          "--autoskip")
            AUTOSKIP=1
            ;;
          "--abandon")
            docmd git am --abort
            docmd rm -f "$PFILE"
            ;;
          "--continue"|"")
            docmd git am --continue
            ;;
          *)
            fatal "We are in git am progress on $(get_patch) patch. Do not use args or check $PFILE file."
        esac
else
        # if first run
        [ -s "$1" ] || fatal "Run me with git log file (use $ git log) or with patch file(s) (use $ git format-patch COMMIT)"

        if is_patch "$1" ; then
                for i in "$@" ; do
                        echo "$i"
                done >$PFILE
        else
                grep "^commit " "$1" | sed -e "s|^commit ||g" -e "s| .*||" >$GFILE || fatal "Can't get commits from $1"
                [ -s "$GFILE" ] || fatal "There is no git log entries in $1 file"
        fi
fi



# has filled file here

# until PFILE is empty
while [ -s "$PFILE" ] ; do
        patch=$(get_patch)

        echo
        echo "Apply patch $patch"
        docmd git am $patch $GITAMOPTIONS && done_patch && continue

        if [ -n "$AUTOSKIP" ] ; then
            git am --skip && continue
        fi

        echo
        echo "Git am for patch $patch is failed. Use --skip or fix conflicts in some way and run $0 without args again."
        exit 1
done

# until GFILE is empty
while [ -s "$GFILE" ] ; do
        # read last line in commit var
        commit=$(get_commit)

        echo
        echo "Cherry picking $(git show --oneline $commit | head -n1)"
        docmd git cherry-pick $commit && done_commit && continue

        if [ -n "$AUTOSKIP" ] ; then
            git cherry-pick abort && continue
        fi

        # cherry pick is failed
        echo
        echo "Cherry pick for commit $commit is failed. Fix conflicts in some way and run $0 without args again."
        exit 1
done
echo "Done."
