#!/bin/bash


# Create a snapshot of a directory
#
# Note:
#	There is an inbuilt assumption of a Java development directory
#	in the default cleanup (-c option) action performed when the
#	target directory does not contain its own cleanup script.
#
# NOTE:
#	The preceding note is no longer valid--cleanup requires an explicit script.



# Give usage message when invoked with no arguments
if [ $# -eq 0 ]; then
	echo "snap: Usage: snap [-D] [-c] [-f]  [-q | -nv | -v]  [-j | -z | -u]  [-m | -h | -d | -t]  [--help]  directory [...]" >&2
	exit 1
fi


# snap: Usage
#	-c			Run target directory's \"clean\" program, if any
#	-D <dir>	Place snapshot file in specified <dir>
#	-f			Force overwrite of existing snapshot file
#	-q			Operate quietly (only error messages)
#	-v			Operate verbosely (list files placed in snapshot)
#	-nv			Operate non-verbosely (only action summary output)
#	-j			Use Bzip2 compression
#	-z			Use Gzip compression
#	-w			Create Zip (a.k.a. WinZip) archive
#	-u			Use no compression
#	-m			Include minute in snapshot file name timestamp
#	-h			Include hour in snapshot file name timestamp
#	-d			Include day in snapshot file name timestamp
#	-t			Include no timestamp in snapshot file name'
#	--help		Print this usage summary

##	-C <dir>	Change directory to specified <dir> before adding files


usageSummary="# snap: Usage
#   -c          Run target directory's \"clean\" program, if any
#   -D <dir>    Place snapshot file in specified <dir>
#   -f          Force overwrite of existing snapshot file
#   -q          Operate quietly (only error messages)
#   -v          Operate verbosely (list files placed in snapshot)
#   -nv         Operate non-verbosely (only action summary output)
#   -j          Use Bzip2 compression
#   -z          Use Gzip compression
#   -w          Create Zip (a.k.a. WinZip) archive
#   -u          Use no compression
#   -m          Include minute in snapshot file name timestamp
#   -h          Include hour in snapshot file name timestamp
#   -d          Include day in snapshot file name timestamp
#   -t          Include no timestamp in snapshot file name'
#   --help      Print this usage summary
"


# Initialize ptions and parameters.
cleanFirst=
allowOverwrite=
replacedSnapshot=
operateQuietly=
zipQuiet=q
compressionSuffix=".tar.bz2"
compressionFlag=j
tarOptions=
dateFormat="%Y-%m-%d@%H"
snapDir=
fileDir=


# Analyze arguments
# for arg; do
while [ $# -gt 0 ]; do
	arg="$1"
	shift

	case "$arg" in
#	-1)
#		# Create a single snapshot file from multiple targets
#		if [ $# -lt 1 ]; then
#			echo "snap: Error: Missing argument to \"-1\" option." >&2
#			exit 1
#		fi

#		archiveName="$1"
#		shift
#		;;

	-c)
		# Clean up first (remove .class files)
		cleanFirst=1
		;;

	-C)
		# Place snapshot files in specified directory
		if [ $# -lt 1 ]; then
			echo "snap: Error: Missing argument to \"-C\" option." >&2
			exit 1
		fi

		# Record the snapshot file output directory
		fileDir="${1%/}/"
		shift
		;;

	-D)
		# Place snapshot files in specified directory
		if [ $# -lt 1 ]; then
			echo "snap: Error: Missing argument to \"-D\" option." >&2
			exit 1
		fi

		# Record the snapshot file output directory
		snapDir="${1%/}/"
		shift
		;;


	-f)
		# Overwrite existing snapshot file
		allowOverwrite=1
		;;


	-j)
		# Bzip2 compression
		compressionFlag=j
		compressionSuffix=".tar.bz2"
		;;

	-z)
		# Gzip compression
		compressionFlag=z
		compressionSuffix=".tar.gz"
		;;

	-w)
		# Zip/PKZIP/WinZip compression
		compressionFlag=w
		compressionSuffix=".zip"
		;;

	-u)
		# No compression
		compressionFlag=
		compressionSuffix=".tar"
		;;


	-m)
		# Include minutes (and hours) in timestamp
		dateFormat="%Y-%m-%d@%H-%M"
		;;

	-h)
		# Include hours in timestamp
		dateFormat="%Y-%m-%d@%H"
		;;

	-d)
		# Include date in timestamp
		dateFormat="%Y-%m-%d"
		;;

	-t)
		# Omit timestamp from snapshot file name
		dateFormat=
		;;


	-q)
		# Produce no standard output
		operateQuietly=1
		zipQuiet=q
		;;

	-nv)
		# Produce minimal progress output
		tarOptions=
		operateQuietly=
		zipQuiet=q
		;;

	-v)
		# Produce detailed progress output
		operateQuietly=
		tarOptions=v
		zipQuiet=
		;;


	--help)
		echo "$usageSummary"
		;;


	-*)
		echo "snap: Error: Unknown option \"$arg\"" >&2
		exit 1
		;;

	*)
		# Validate the directory (or file) name argument
		if [ ! -e "$arg" ]; then
			echo "snap: Error: There is no file or directory named \"$arg\"" >&2
			continue
		fi

		if [ ! -d "$arg" ]; then
			echo "snap: Warning: \"$arg\" is not a directory." >&2
		fi

		baseName="${arg##*/}"

		case "$baseName" in
		"")	baseName=DOT ;;
		.*)	baseName=DOT."${baseName#.}" ;;
		esac

		# Clean up .class files, if requested.
		if [ -n "$cleanFirst" ]; then
			# Invoke directory-specific cleanup program, if any
			if [ -x "$arg/clean" ]; then
				(cd "$arg"; clean)
			else
				echo "snap: Warning: No \"clean\" program in \"$arg\"" >&2
			fi
		fi


		# Generate the date code to embed in the resulting snapshot file.
		if [ -z "$dateFormat" ]; then
			dateString=
		else
			dateString="-$(date +"$dateFormat")"
		fi


		# Generate the snapshot file name
		snapshotName="$snapDir${baseName}$dateString$compressionSuffix"


		# Check for already existing snapshot file.
		if [ -f "$snapshotName" ]; then
			if [ -z "$allowOverwrite" ]; then
				echo "snap: Error: Snapshot file \"$snapshotName\" already exists and the -f option is absent." 2>&1
				continue
			else
				replacedSnapshot=1
			fi
		fi


		# Create the snapshot file.
		if [ "$compressionFlag" = "w" ]; then
			zip -r9l$zipQuiet "$snapshotName" "$arg"
		else
			tar ${tarOptions}${compressionFlag}cf "$snapshotName" "$arg"
		fi


		# Report
		if [ -z "$operateQuietly" ]; then
			if [ -n "$replacedSnapshot" ]; then
				echo "Replaced snapshot \"$snapshotName\""
			else
				echo "Created snapshot \"$snapshotName\""
			fi
		fi
		;;
	esac
done
