#!/bin/bash
# piscal manager script

usage="$(basename "$0") [-h] 
    -d directory_name
    [-s|-c|-k]
    -p photosynthetic_type
    -u notify_url
    -t

where:
    -h  show this help text
    -d  working directory name
    -s  start job
    -c  cleanup directory
    -k  kill job
    -u  url to notify on completion
    -p  photosynthetic type
    -t  suppress storage copy"

# Initialize variables:
# http://stackoverflow.com/a/246128/99492
base_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
directory_name=""
photosynthetic_type="C3_photosynthesis_leafweb" #default
task="get_status" # default task
input_directory_name="input"
pid_filename="piscal.pid"
stderr_filename="piscal.err"
cleaned_input_directory_name="output/clninput"
output_directory_name="output/fitresult/touser"
nottouser_directory_name="output/fitresult/nottouser"
launcher="$base_directory/piscal_launcher.sh"

# http://stackoverflow.com/a/14203146/99492
# http://wiki.bash-hackers.org/howto/getopts_tutorial

while getopts "hd:f:p:stcku:" opt; do
    #echo "$opt = $OPTARG"
    case "$opt" in
    h )
        echo "$usage"
        exit
        ;;
    d )
        directory_name=$OPTARG
        ;;
    p )
        photosynthetic_type=$OPTARG
        ;;
    s )
        task="launch"
        ;;
    t )
        suppress_storage_copy=true
        ;;
    c )
        task="cleanup"
        ;;
    k )
        task="kill"
        ;;
    u )
        notify_url=$OPTARG
        ;;
    \?) printf "illegal option: -%s\n" "$OPTARG" >&2
        echo "$usage" >&2
        exit 1
        ;;
    esac
done

## Examine directories
if [ -z "$directory_name" ]; then
    echo "directory name required (-d)"
    exit 1
fi
working_directory="$base_directory/$directory_name"
if [ ! -d "$working_directory" ]; then
    echo "working directory $working_directory not found"
    exit 1
fi
input_directory="$working_directory/$input_directory_name"
if [ ! -d "$input_directory" ]; then
    echo "input directory $input_directory not found"
    exit 1
fi
pid_path="$working_directory/$pid_filename"

## Process task
if [ "$task" = "launch" ]; then
    # verify process isn't running yet
    pid=$(head -n 1 $pid_path 2>/dev/null)
    # if the pid exists, check the process status using ps
    if ps -p $pid &>/dev/null; then
        # if it is in ps, then it's still running
        echo still running
        exit 1
    fi
    
    piscal_config_file="$working_directory"/piscal.cfg
    # write config file for piscal
    echo $photosynthetic_type > "$piscal_config_file"
    find "$input_directory" -maxdepth 1 -type f\
        -printf '%P\n'\
        >> "$piscal_config_file"
    
    command="$launcher -d $working_directory -f piscal.cfg"
    if [ "$suppress_storage_copy" = true ]; then
        command="$command -t"
    fi

    if [ -n "$notify_url" ]; then
        command="$command -u $notify_url"
    fi

    # launch it, sending error output to file
    nohup ${command} > $working_directory/$stderr_filename 2>&1 &

    # write the PID to a temp file to check for completion later
    echo $! > $pid_path
    echo started
elif [ "$task" = "get_status" ] || [ "$task" = "get_status_cleaned_input" ]; then
    # if the pid doesn't exist, then process hasn't started
    if [ ! -f "$pid_path" ]; then
        echo "not started"
        exit
    fi

    pid=$(head -n 1 $pid_path 2>/dev/null)
    # if the pid exists, check the process status using ps
    if ps -p $pid > /dev/null; then
        # if it is in ps, then it's still running
        echo running
    else
        # otherwise, it is complete, check for runtime errors
        if [ -s "$working_directory/$stderr_filename" ]; then
            cat "$working_directory/$stderr_filename"
            exit 1
        fi
        
        output_directory="$working_directory/$output_directory_name"
        if [ ! -d "$output_directory" ]; then
            echo "output directory $output_directory not found"
            exit 1
        fi
        
        echo complete
        if [ "$task" = "get_status" ]; then
            echo "#touser"
            find "$output_directory"/* 2>/dev/null
            
            cleaned_input_directory="$working_directory/$cleaned_input_directory_name"
            echo "#clninput"
            find "$cleaned_input_directory"/* 2>/dev/null
            
            nottouser_directory="$working_directory/$nottouser_directory_name"
            echo "#nottouser"
            find "$nottouser_directory"/* 2>/dev/null
            exit 0
       fi
    fi
elif [ "$task" = "cleanup" ]; then
    pid=$(head -n 1 $pid_path 2>/dev/null)
    # if the pid exists, check the process status using ps
    if ps -p $pid > /dev/null; then
        # if it is in ps, then it's still running
        echo still running
        exit 1
    fi
    rm -rf "$working_directory"
elif [ "$task" = "kill" ]; then
    # if the pid doesn't exist, then process hasn't started
    if [ ! -f "$pid_path" ]; then
        echo "not started"
        exit 1
    fi

    pid=$(head -n 1 $pid_path 2>/dev/null)
    # if the pid exists, check the process status using ps
    if ps -p $pid > /dev/null; then
        # if it is in ps, then it's still running
        kill $pid
    fi
    echo killed
fi
