#!/bin/bash

set -e

textbf=$(tput bold)
textnm=$(tput sgr0)
startul=$(tput smul)
endul=$(tput rmul)

function int2bool {
    T="true/on"
    F="false/off"
    if [ $1 == 1 ]; then echo ${T}; else echo ${F}; fi
}

verbose=0
timer=0
runs=()
cmndstr=

cliname=${0##*/}

show_help()
{
    echo "
${textbf}NAME${textnm}
        $cliname - Run a project-specific script in batch mode

${textbf}SYNOPSIS${textnm}
        ${textbf}$cliname${textnm} ${startul}COMMAND${endul} [${startul}OPTIONS${endul}]

${textbf}DESCRIPTION${textnm}
        This routine will iteratively run COMMAND in multiple directories. Note 
        that COMMAND must be the first argument and it must be quoted if it 
        includes arguments.

        ${textbf}-h${textnm}, ${textbf}--help${textnm}
                Display help and exit.
        ${textbf}-v${textnm}, ${textbf}--verbose${textnm}
                Print runtime messages.
                Default: $(int2bool ${verbose})
        ${textbf}--time${textnm}
                Report timing information.
                Default: $(int2bool ${verbose})
        ${textbf}--runs${textnm} ${startul}RUN${endul} [${startul}RUN${endul} ...]
                Directories in which to execute COMMAND. The default behavior 
                is to run COMMAND in each of a predefined set of 
                project-specific directories.
"
}

TEMP=$(getopt \
    -n $cliname \
    -o '+hv' \
    -l 'help,verbose,' \
    -l 'args:,runs:,program:' \
    -- "$@")

if [ $? -ne 0 ]; then
    echo "Failed to parse command-line arguments. Terminating."
    exit 1
fi

eval set -- "$TEMP"
unset TEMP

while [ $# -gt 0 ]; do
    case "$1" in
        '-h'|'--help')
            show_help
            exit
        ;;
        '-v'|'--verbose')
            verbose=1
            shift
            continue
        ;;
        '--time')
            timer=1
            shift
            continue
        ;;
        '--runs')
            shift
            while [ -n "$1" ]; do
                runs+=( "$1" )
                shift
            done
            continue
        ;;
        *)
            cmndstr="$2"
            shift 2
            continue
        ;;
        '--')
            shift
            break
        ;;
    esac
done

function report {
    if [ $verbose == 1 ]; then
        echo "${1-}"
    fi
}

scripts="$(dirname "$(realpath  --canonicalize-existing ${0})")"
projdir="$(dirname ${scripts})"

echo "Updating run links"
${scripts}/link-runs

. define-aliases

if [ -z "$runs" ]; then
    runs=${WIDESPREAD_EVENTS[@]}
fi

command=( $cmndstr )
command[0]=$(realpath --canonicalize-existing ${command[0]})

report 
report "Running $command"
report "Starting at $(date +%T)"
report 
if [ $timer == 1 ]; then
    for run in ${runs[@]}; do
        pushd ${projdir}/runs/${run} &> /dev/null \
        && time ${command[@]} \
        && popd &> /dev/null
    done
else
    for run in ${runs[@]}; do
        pushd ${projdir}/runs/${run} &> /dev/null \
        && ${command[@]} \
        && popd &> /dev/null
    done
fi
report 
report "Finished at $(date +%T)"
