#!/usr/bin/env bash
#
# 2D or 3D, low or high resolution, ODM assembly script
# xxx git version macro goes here

# to do 
# 	separate script to move a set of output directories to /cluster/fieldscience/artifacts/image-analysis/...
# 		move.sh 
# 			cp nohup-$RUNID to destdir
# 			${var#*SubStr}
#
#	interface - image source dir, dest dir prefix, 
# 	command line overrides for resolution paramters (fast field assembly mode) 
# 	check parameters and bail if any are not set
# 	is $pwd required for Docker or can we use absolute paths?
# 	why not python?
#	clean _.DJI... files, prune low ones from each end?

# --crop = 0 disable, try 1-5 or so (by meters)

set -euo pipefail
VERBOSE=false
CLEANUP=false

# Usage information. Gets displayed if the arguments are not entered correctly.
usage()
{
cat << EOF
usage example: nohup ./assemble-odm.sh -r medium -i roundhouse-skalanes/images -d 2 -e dkvart17@earlham.edu -v &
-r    | --resolution        (required)            The quality of the mesh. Available options: medium, high, ultra
-i    | --images-directory  (required)            The relative path to the directory where the images live
-d    | --dimensions        (required)            Produces either 2D or 3D meshes. Available options: 2, 3
-e    | --email             (required)            Email address where the logs will be sent to
-v    | --verbose                                 More debugging output
-c    | --cleanup                                 If this job has already run, this option will delete the previous assembly
-h    | --help                                    Brings up usage
EOF
}


# Parse the command line arguments.
while [[ $# -gt 0 ]]
do
arg="$1"

case $arg in
    -r|--resolution)
    	RESOLUTION="$2"
    	shift
    	shift
    ;;
    -i|--images-directory)
    	IMAGES_DIRECTORY="$2"
    	shift
    	shift
    ;;
    -d|--dimensions)
    	DIMENSIONS="$2"
    	shift
    	shift
    ;;
    -e|--email)
		EMAIL_ADDRESS="$2"
		shift
		shift
	;;
	-v|--verbose)
		VERBOSE=true
		shift
	;;
	-c|--cleanup)
		CLEANUP=true
		shift
	;;
    -h|--help)
    	usage
    	exit 0
    ;;
    *)    # unknown option
    shift # past argument. Just ignore the rest
    ;;
esac
done

# Checking if all required arguments were passed 
if [[ -z ${RESOLUTION+x} || -z ${IMAGES_DIRECTORY+x} || -z ${DIMENSIONS+x} || -z ${EMAIL_ADDRESS+x} ]]; then
	echo "You didn't set the parameters correctly!"
	usage
	exit 1
fi

# mesh quality
if [[ ( "$RESOLUTION" == "medium" ) ]]; then
	MNF=12000
	MS=150000
	MOD=10
	QUALITY="medium"
elif [[ ( "$RESOLUTION" == "high" ) ]]; then
	MNF=24000
	MS=300000
	MOD=11
	QUALITY="high"
elif [[ ( "$RESOLUTION" == "ultra" ) ]]; then
	MNF=36000
	MS=400000
	MOD=12
	QUALITY="ultra"	

else
	echo "unknown RESOLUTION" $RESOLUTION
	usage
	exit 1
fi

# Checking if directory exists
if [[ ! -d $IMAGES_DIRECTORY ]]; then
	echo "Directory $IMAGES_DIRECTORY does not exist!"
	usage
	exit 1
fi


# dimensions 
if [[ ( "$DIMENSIONS" == 2 ) ]]; then 
	DIMS="--fast-orthophoto --orthophoto-png"

elif [[ ( "$DIMENSIONS" == 3 ) ]]; then 
	DIMS="--dsm"

else 
	echo "unknown DIMENSIONS" $DIMENSIONS
	usage
	exit 1
fi

RUNID="$DIMENSIONS"D-$RESOLUTION
IMAGES_DIRECTORY="`cd "${IMAGES_DIRECTORY}";pwd`" #normalizes the path
WORKING_DIRECTORY=$(dirname $IMAGES_DIRECTORY)/$RUNID

cat << EOF
Initializing ODM with the following parameters..
================================================================================================
RESOLUTION: $RESOLUTION
DIMENSIONS: $DIMENSIONS
RUNID: $RUNID
IMAGES_DIRECTORY: $IMAGES_DIRECTORY
WORKING_DIRECTORY: $WORKING_DIRECTORY
EMAIL_ADDRESS: $EMAIL_ADDRESS
================================================================================================
EOF


# directories and the rest of the command line
COMMAND_LINE="docker run --detach \
-v \"$IMAGES_DIRECTORY:/code/images\" \
-v \"$WORKING_DIRECTORY/odm-orthophoto:/code/odm_orthophoto\" \
-v \"$WORKING_DIRECTORY/odm-texturing:/code/odm_texturing\" \
-v \"$WORKING_DIRECTORY/odm-dem:/code/odm_dem\" \
-v \"$WORKING_DIRECTORY/odm-meshing:/code/odm_meshing\" \
-v \"$WORKING_DIRECTORY/odm-georeferencing:/code/odm_georeferencing\" \
opendronemap/odm $DIMS \
--min-num-features $MNF --mesh-size $MS --mesh-octree-depth $MOD \
--pc-quality $QUALITY --feature-quality $QUALITY --time"

if [[ -d $WORKING_DIRECTORY ]]; then
	if [ "$CLEANUP" = true ]; then
		echo "Cleaning up... Deleting $WORKING_DIRECTORY"
		rm -rf $WORKING_DIRECTORY
	else
		echo "ABORT! This job has already run..."
		echo "If you want to overwrite its output, run the command with -c option."
		exit 1
	fi
	echo "================================================================================================"	
fi

mkdir $WORKING_DIRECTORY

if [ "$VERBOSE" = true ]; then
	echo "Running the following command ==>"
	echo "$COMMAND_LINE"
fi

CID=$(eval "$COMMAND_LINE")

echo
echo "Container ID: $CID"

docker wait $CID
docker logs $CID
docker rm $CID

mv nohup.out $WORKING_DIRECTORY/log

cat $WORKING_DIRECTORY/log | mailx -s "Your job $RUNID completed on $HOSTNAME" $EMAIL_ADDRESS

echo "SUCCESS!"
exit 0

# basename plus runid, should source and dest be automated at all? (prefix, only for moving ODM runs
# odm-run and odm-move )
# for file in Skalanes-Arch-1-VLI-2019-2D*; do sudo mv $file /cluster/fieldscience/artifacts/image-analysis/Skalanes/Arch-1-VLI-2019/${file##*2019-}; done
# mv nohup-Skalanes-Arch-1-VLI-2019-2D.out /cluster/fieldscience/artifacts/image-analysis/Skalanes/Arch-1-VLI-2019/
