#!/bin/bash

cur_line=0
column=1

function usage()
{
	echo -e "`basename $0` [OPTION]... commit list"
	echo
	echo "[OPTION]:"
	echo -e "  -h, --help\t\t\tshow this help info"
	echo -e "  -c, --column\t\tsort by which column, column 1 by default"
	echo
	echo "  In normal cases, refer to Example-1."
	echo "  Example-1:"
	echo -e "  `basename $0` upstream.list"
	echo
	echo "  If your list has more than 1 column,  refer to Example-2."
	echo "  for example, column 1 is downstream, column 2 is upstream"
	echo "  Example-2:"
	echo -e "  `basename $0` -c 2 input.list"
}

ARGS=`getopt -o hc: -a --long help,column: -- "$@"`
if [ $? != 0 ]; then
	echo "Terminating..."
	usage && exit -1
fi

eval set -- "${ARGS}"

while true
do
	case $1 in
		-h|--help)
			usage
			exit -1;;
		-c|--column)
			column="$2"
			shift 2;;
		--)
			shift
			break;;
	esac
done

function pre_process() {
	# TODO
	# remove empty lines
	sed -i '/^[[:space:]]*$/d' $1
}

function swap_2_line() {
	local linea=$1
	local lineb=$2
	{
		printf '%dm%d\n' "$linea" "$lineb"
		printf '%d-m%d-\n' "$lineb" "$linea"
		printf '%s\n' w q
	} | ed -s $3
	echo -e "switch $linea" "$lineb"
}

function sort_commit_by_deps() {
	# input file with sorted commits
	if [ $# -ne 1 ]; then
		echo "$0 needs input"
		exit 1
	fi

	echo -e "commit\t\tline\tpercentage"
	for LINE in $(tail -n +$(($cur_line+1)) $1 |  awk '{print $'$column'}')
	do
		# check whether the dependency is in the behind
		local_deps=$(git deps $LINE...$LINE^)
		cur_line=$(($cur_line+1))

		# percentage of sorted commits
		percentage=$(bc <<<"scale=2;$(($cur_line*100))/$total_lines")

		# get short hash of LINE, only for debuging
		SHORT_HASH=$(git log -1 --pretty=%h "$LINE"
				2> /dev/null)
		# show current HASH and line number
		echo -e "$SHORT_HASH\t$cur_line\t$percentage%"
		for local_dep in $local_deps
		do
			_UP_HASH_SHORT=$(git log -1 --pretty=%h "$local_dep"
				2> /dev/null)

			# get line number of deps commit in input commit list
			dep_line_number=$(cat -n $1 | tail -n \
				+$cur_line | head -n $total_lines | grep \
				"$_UP_HASH_SHORT" | awk '{print $1}')
			if [ ! -z $dep_line_number ]; then
				# dependency is in the behind
				# swap 2 line
				swap_2_line $cur_line $dep_line_number $1

				# manually check
				#/bin/bash

				# update cur_line because it'll +1
				# outside this loop
				cur_line=$(($cur_line-1))

				# break and start from cur_line again
				break 2
			fi
		done
	done
}

input_commit_list=$1
temp_commit_list=$(mktemp)

awk -F " " ' { print $0 }' < "$input_commit_list" > "$temp_commit_list"

# Step 1, pre process commit lines
pre_process $temp_commit_list

total_lines=$(cat $temp_commit_list | wc -l)
echo -e "total lines: $total_lines"

# Step 2, sort commits in temp file
for ((;;))
do
	if [ $cur_line -ne $total_lines ]; then
		sort_commit_by_deps $temp_commit_list
	else
		echo -e "cur_line: $cur_line\n"
		break;
	fi
done

# Step 3, update source file
awk -F " " ' { print $0 }' < "$temp_commit_list" > "$input_commit_list"

# Step 4, remove temp file
[ -f $temp_commit_list ] && rm -f $temp_commit_list

exit 0
