#!/usr/bin/env bash

# machete-pre-rebase hook is invoked before each rebase operation.
# Unlike the standard 2-parameter pre-rebase it receives three parameters corresponding to the parameters of `git rebase --onto`.

# This particular example shifts the files stored in a specific directory so that they remain correctly sequentially numbered after the rebase.

if [ $# -eq 3 ]; then
    # Path for Play framework evolution files.
    evolution_dir=app/src/main/resources/evolutions/default
    [ -d $evolution_dir ] || exit 0

    new_base=$1
    fork_point=$2
    current_branch=$3

    function max_evolution_number() {
        git ls-tree -r --name-only "$1" -- $evolution_dir | xargs basename -s .sql | sort -n | tail -1
    }

    current_branch_max=$(max_evolution_number "$current_branch")
    new_base_max=$(max_evolution_number "$new_base")
    fork_point_max=$(max_evolution_number "$fork_point")
    offset=$((new_base_max - fork_point_max))

    if [ $offset -gt 0 ]; then
        self_path="$(cd "$(dirname "$0")" &>/dev/null; pwd -P)"/"$(basename "$0")"
        git filter-branch -f --tree-filter "$self_path $evolution_dir $((fork_point_max + 1)) $current_branch_max $offset" "$fork_point".."$current_branch"
    fi
elif [ $# -eq 4 ]; then
    evolution_dir=$1
    first_to_shift=$2
    last_to_shift=$3
    offset=$4

    cd "$evolution_dir" || exit

    # We have to iterate from highest to lowest evolution to prevent unwanted overwrites during move.
    # If we iterated from lowest to highest, then when moving files in the interval [10,12] by offset=1 we would end up with the following sequence of moves:
    # mv 10.sql 11.sql; mv 11.sql 12.sql; mv 12.sql 13.sql
    # and thus effectively the original 10.sql will be moved to 13.sql, and the original 11.sql & 12.sql will be non-existent in the rebased commits.
    any_moved=false
    for src_number in $(seq "$last_to_shift" -1 "$first_to_shift"); do
        src=$src_number.sql
        if [ -f "$src" ]; then
            dst_number=$((src_number + offset))
            dst=$dst_number.sql
            mv "$src" "$dst"
            $any_moved || echo
            any_moved=true
            echo Moved "$src" to "$dst"
        fi
    done
fi
