#!/bin/sh

unset CDPATH	# See https://bosker.wordpress.com/2012/02/12/bash-scripters-beware-of-the-cdpath/

# shellcheck disable=SC1091
command -v realpath >/dev/null 2>&1 ||
    realpath() { test -z "${1%%/*}" && echo "$1" || echo "$PWD/${1#./}"; }

# Boilerplate ends 

PATH=$PATH:./..

build=T
view=F
edit=F
stream=F
cleanup=T
strip=F
co=F
log=""
quiet=""
limit=""
# Suppress legacy emission by default
streamopts='prefer git'

# Built-in echo insidiously expands backslash escapes.  This is a problem
# when stripping... 
ECHO=/bin/echo

while getopts cdeghl:noqr:st opt
do
    case $opt in
        e) build=F; view=F; edit=T; stream=F; dump=F; cleanup=T; strip=F; co=F;;
	c) build=T; view=F; edit=F; stream=F; dump=F; cleanup=F; strip=F; co=T;;
	n) build=T; view=F; edit=F; stream=F; dump=F; cleanup=F; strip=F; co=F;;
        g) build=F; view=T; edit=F; stream=F; dump=F; cleanup=F; strip=F; co=F;;
        o) build=F; view=F; edit=F; stream=T; dump=F; cleanup=F; strip=F; co=F;;
        d) build=F; view=F; edit=F; stream=F; dump=T; cleanup=F; strip=F; co=F;;
        s) build=F; view=F; edit=F; stream=F; dump=F; cleanup=F; strip=T; co=F;;
	t) streamopts="" ;;
	q) quiet=-q ;;
	r) limit="$OPTARG" ;;
	l) log="log $OPTARG" ;;
	h) cat <<EOF
svn-to-svn - Subversion dump on stdin to dump on stdout

With the -c option, build the repo and check it out to a working
copy.  The name of the working copy is the repo name suffixed with
'-checkout'.

With the -d option, expect the repo to exist, undump the repo to
a Subversion dump file; then do not delete the repo.

With the -e option, edit a Subversion dumpfile and rebuild it, fixing
the checksum headers.

With the -g option, make a Git repo from the Subversion dump and view
it in gitk

Any -l option argument will be used to set reposurgeon's log option.

With the -n option, create a repo corresponding to the input stream;
do not stream the result to stdout and do not delete the repo.

With the -o option, expect the repo to exist, pick it up with
reposurgeon, and throw the result to stdout as an import stream;
then do not delete the repo.

With the -q option. suppress progress messages from svnadmin load
and checkout.

With the -r option, limit the number of Subversion revisions processed
from the input dump; the specified argument is the number of the last
revision emitted.

The -s option strips out generated time-varying headers - the UUID and
the timestamp in revision zero.  This is necessary for file comparisons 
in regression tests.

The -t option allows property extensions to be generated.  It's turned
off by default because git-import chokes on it.

If an argument is specified after the options, it is used as the repository
directory name; otherwise 'test-repo' is used.

To add complexity to a test load, do -n, then edit the test repo with
Subversion, then use -d. Note: you must commit to force the repo to
be up to date before streaming it. Also note that any embedded comments
will be lost.

The REPOSURGEON environment variable can be used to substitute in a
different implementation.

The TESTOPT variable can be used to pass an early command or option setting
to reposurgeon.
EOF
	   exit 0
	   ;;
	*) echo "$0: unknown flag $opt" >&2; exit 1;;
    esac
done
# shellcheck disable=SC2004
shift $(($OPTIND - 1))

tmpdir=${TMPDIR:-/tmp}

# This lets us set the repo location 
# shellcheck disable=SC2006,2046,2086
testrepo=`realpath \`dirname ${1:-test-repo$$}\``/`basename ${1:-test-repo$$}`

# Should we strip time-varying headers out of the input dump file?
if [ $strip = T ]
then
    seen_uuid=F
    seen_date=F
    while IFS= read -r line
    do
	case $line in
	    [0-9]*)
		if [ $seen_date = T ]; then $ECHO "$line"; fi ;  
		seen_date=T ;;
	    UUID*)  
		if [ $seen_uuid = T ]; then $ECHO "$line"; fi ; 
		seen_uuid=T ;;
	    *) $ECHO "$line" ;;
	esac
    done
fi

# Was there a limit option?
if [ -z "$limit" ]
then
    source=/dev/stdin
else
    source="${tmpdir}/svn-to-svn-$$"
    ../repocutter -r "0:${limit}" select >"${source}"
fi

# Should we build a repo from a dump presented on standard input?
if [ $build = T ]
then
    rm -fr "$testrepo" "$testrepo-checkout"
    svnadmin create "$testrepo"
    # shellcheck disable=2086
    if svnadmin load ${quiet} "$testrepo" <"$source"
    then
	:
    else
	exit 1
    fi
fi

if [ "$co" = T ]
then
    # shellcheck disable=2086
    svn co ${quiet} "file://$testrepo" "${testrepo}-checkout" >/dev/null
fi

# Should we edit the streamfile?
if [ "$edit" = T ]
then
    dump=$1
    if [ -z "$dump" ]
    then
	echo "svn-to-svn: a file argument is required" >&2
	exit 1
    elif "$EDITOR" "$1"
    then
	rm -fr "$testrepo" test-checkout
	svnadmin create "$testrepo"
	sed  <"$dump" \
	    -e '/Text-content-md5: /d' -e '/Text-content-sha1: /d' \
	    -e '/Text-copy-source-md5: /d' -e '/Text-copy-source-sha1: /d' \
	    | svnadmin load "$testrepo" >/dev/null
	svnadmin dump "$testrepo" >"$dump"
    fi
fi

# Should we view the repo?
if [ "$view" = T ]
then
    (cd "$testrepo" >/dev/null || (echo "$0: cd failed" >&2; exit 1); ${REPOSURGEON:-reposurgeon} "${log}" "${TESTOPT}" "read ." "prefer git" "rebuild ${tmpdir}/testrepo$$"; cd "${tmpdir}/testrepo$$" 2>/dev/null || (echo "$0: cd failed"; exit 1); gitk --all --tags)
fi

# Should we dump a conversion of the repo as a fast-import stream?
if [ "$stream" = T ]
then
    ${REPOSURGEON:-reposurgeon} "${log}" "${TESTOPT}" "read $testrepo" "$streamopts" "write"
fi

# Should we dump the repo as a Subversion stream?
if [ "$dump" = T ]
then
    svnadmin dump "$testrepo"
fi

# Should we clean up the test directory
if [ "$cleanup" = T ]
then
    rm -fr "$testrepo" test-checkout
fi
