#!/bin/bash
# Perform diff of local sandbox file against earlier copy
# Copyright (C) 2012 - 2019 FARGOS Development, LLC
# $Id$
# PORTABILITY NOTE: this uses arrays to preserve the structure of each
# command line token.
# Since bash was chosen as the implementation target, native arithmetic
# expressions are used.

diffProg="${SB_DIFF_PROG:-gvimdiff}"
targetRevision=""
noWhiteSpace=0
flags=""
vimDiffFlags=""
fileCount=0
repositoryType=""


declare -a fileList # this will be an array

while test $# -gt 0
do
	case "${1}" in
	-h | -help | --help) 
		printf "usage: %s [{--svn | --git}] [{-r revision | --local | --committed }] [--diff] [--nows] [--using prog] {fileName [--against anotherFileName]} ...\n" "${0}" >&2
		exit 1
		;;
	-r | --revision)
		targetRevision="${2}"
		shift
		;;
	-d | -diff | --diff)
		diffProg="diff"
		flags="${flags}${flags:+ }-u -d"
		;;
	-local | --local)
		targetRevision=""
		;;
	-committed | --committed)
		targetRevision="HEAD"
		;;
	-svn | --svn)
		repositoryType="svn"
		targetRevision="HEAD"
		;;
	-git | --git)
		repositoryType="git"
		targetRevision=""
		;;
	-w | -nows | --nows)
		vimDiffFlags="${vimDiffFlags}${vimDiffFlags:+,}iwhite"
		flags="${flags}${flags:+ }-w"
		;;
	-i | -ignore-case | --ignore-case)
		vimDiffFlags="${vimDiffFlags}${vimDiffFlags:+,}icase"
		flags="${flags}${flags:+ }-i"
		;;
	-using | --using)
		diffProg="${2}"
		shift
		;;
	-against | --against)
		eval originalFile${fileCount}="${2}"
		shift
		;;
	-*)
		printf "%s: unrecognized option \"%s\"\n" "${0}" "${1}" >&2
		exit 1
		;;
	*)
		fileCount=$(( fileCount + 1 ))
		fileList[${fileCount}]="${1}"
		;;
	esac
	shift
done

if test -z "${repositoryType}"
then # not forced
	if test -d "${STS}/.git" -o -d "./.git"
	then
		repositoryType="git"
	else
		if test -d "${STS}/.svn" -o -d "./.svn"
		then
			repositoryType="svn"
		fi
	fi
fi

cleanupList=""
count=0
origRepositoryType="${repositoryType}"

for f in "${fileList[@]}"
do
	repositoryType="${origRepositoryType}"
	if test -z "${repositoryType}"
	then
		d=`dirname ${f}`
		asPath=`readlink -m ${d}`
		if test "${asPath}" = "${lastDir}"
		then # already determined
			respositoryType="${lastRepository}"
		fi
		while test -z "${repositoryType}" -a "${asPath}" != "/"
		do
			if test -d "${asPath}/.git"
			then
				repositoryType="git"
				break
			fi
			if test -d "${asPath}/.svn"
			then
				repositoryType="svn"
				break
			fi
			asPath=`dirname ${asPath}`
		done
		lastDir="${asPath}"
		lastRepository="${repositoryType}"
	fi
	count=$(( count + 1 ))
	eval origFile=\$originalFile${count}
	if test -z "${origFile}"
	then
		suffix=`basename "${f}" | sed -e 's/ /_/g'`
		origFile="/tmp/tmp.sbDiff_$$.${count}_${suffix}"
		cleanupList="${cleanupList}${cleanupList:+ }${origFile}"
		case "X${repositoryType}Y" in
		XsvnY)
			echo svn cat --revision ${targetRevision:-BASE} "${f}"
			svn cat --revision ${targetRevision:-BASE} "${f}" > ${origFile}
			;;
		XgitY)
			dirPath=`dirname "${f}"`
			baseFile=`basename "${f}"`
			echo git show ${targetRevision:-HEAD}:"${dirPath}/${f}"
			git show ${targetRevision:-HEAD}:"${dirPath}/${f}" > ${origFile}
			;;
		XY)
			printf "%s:  cannot infer repository type\n" "${0}" >&2
			exit 1
			;;
		esac
	fi
	printf "File: %s\n" "${origFile}"
	ls -l "${origFile}"
	if test ! -s "${origFile}"
	then
		printf "ERROR: could not extract revision %s of %s.\n" ${targetRevision} ${f} >&2
		continue
	fi
	vimDiffInUse=`expr ${diffProg} : '.*'vimdiff`
	if test ${vimDiffInUse} -ne 0 -a -n "${vimDiffFlags}"
	then
		${diffProg} -c 'set diffopt+='${vimDiffFlags} "${origFile}" "${f}"
	else
		${diffProg} ${flags} "${origFile}" "${f}"
	fi
	sleep 1
done

sleep 1
if test -n "${cleanupList}"
then
	rm -f ${cleanupList}
fi
