#!/bin/bash

green="\e[1;32m"
magenta="\e[1;35m"
cyan="\e[1;36m"
yellow="\e[33m"
red="\e[31m"
bold_red="\e[31;1m"
blue="\e[34m"
reset="\e[0m"
cr="\e[F"
upline="\e[A"

function schedule_scripts {
    for script in schedule_$RUN_PLATFORM*.sh
    do
        cmd="./$script"
        echo "$cmd"
        "$cmd"
    done
}

config_filename=$( spt-print config-filename )
if [[ -f "$config_filename" ]]; then
    printf "$yellow""Regenerating jobs and scheduling them.""$reset\n"
    printf "$yellow""Using parameters from $reset""$magenta$config_filename$reset$yellow.$reset\n"
    printf "$yellow""To reconfigure, update or delete $magenta$config_filename$reset\n"
    spt-generate-jobs
    chmod +x *.sh
    config_filename=$(spt-print config-filename)
    RUN_PLATFORM=$(grep 'runtime_platform = .*$' $config_filename | grep -oE '\w+$')
    schedule_scripts
    exit
fi

function abspath {
    if [[ -d "$1" ]]
    then
        pushd "$1" >/dev/null
        pwd
        popd >/dev/null
    elif [[ -e "$1" ]]
    then
        pushd "$(dirname "$1")" >/dev/null
        echo "$(pwd)/$(basename "$1")"
        popd >/dev/null
    else
        echo "$1" does not exist! >&2
        return 127
    fi
}

workflows=()
IFS=$'\n' read -r -d '' -a workflows < <( spt-print computational-workflows && printf '\0' )
show_prompt_str () {
    printf "$yellow""Enter the computational workflow type""$reset"
    printf " $magenta(  "
    first_entry=""
    for workflow in "${workflows[@]}"
    do
        if [[ "$first_entry" == "" ]];
        then
            printf "$cyan$workflow$reset  "
            first_entry="0"
        else
            printf "$magenta$workflow$reset  "
        fi
    done
    printf "$magenta)$reset$yellow: $reset"
}

COMPUTATIONAL_WORKFLOW="none"
while [[ "$COMPUTATIONAL_WORKFLOW" = "none" ]];
do
    show_prompt_str
    read -e COMPUTATIONAL_WORKFLOW_READ
    for workflow in "${workflows[@]}"
    do
        if [[ "$COMPUTATIONAL_WORKFLOW_READ" = "$workflow" ]];
        then
            COMPUTATIONAL_WORKFLOW=$COMPUTATIONAL_WORKFLOW_READ
        fi
    done

    if [[ "$COMPUTATIONAL_WORKFLOW_READ" == "" ]];
    then
        COMPUTATIONAL_WORKFLOW="${workflows[0]}"
        echo
    fi

    if [[ "$COMPUTATIONAL_WORKFLOW" != "none" ]];
    then
        printf "$cr"
        show_prompt_str
        printf "$green$COMPUTATIONAL_WORKFLOW$reset"
        echo
    fi
done

SIF_PATH=""
prompt_str="Enter the Singularity container file (.sif) containing the toolbox: "
printf "$yellow$prompt_str$reset"
while [[ "$SIF_PATH" = "" ]];
do
    read -e SIF_PATH
done
SIF_PATH=$(abspath $SIF_PATH)
printf "$cr$yellow$prompt_str$reset$green$SIF_PATH$reset\n"

INPUT_PATH=""
prompt_str="Enter the path containing input cell location CSV files: "
printf "$yellow$prompt_str$reset"
while [[ "$INPUT_PATH" = "" ]];
do
    read -e INPUT_PATH
done
INPUT_PATH=$(abspath $INPUT_PATH)
printf "$cr$yellow$prompt_str$reset$green$INPUT_PATH$reset\n"

FILE_MANIFEST=""
prompt_str="Enter the file manifest file: "
printf "$yellow$prompt_str$reset"
while [[ "$FILE_MANIFEST" = "" ]];
do
    read -e FILE_MANIFEST
done
FILE_MANIFEST=$(abspath $FILE_MANIFEST)
printf "$cr$yellow$prompt_str$reset$green$FILE_MANIFEST$reset\n"

OUTCOMES_FILE=""
prompt_str="Enter the file containing outcomes data (or \"$magenta""None""$reset$yellow\"): "
printf "$yellow$prompt_str$reset"
while [[ "$OUTCOMES_FILE" = "" ]];
do
    read -e OUTCOMES_FILE
done
OUTCOMES_FILE=$(abspath $OUTCOMES_FILE)
printf "$cr$yellow$prompt_str$reset$green$OUTCOMES_FILE$reset\n"

OUTPUT_PATH="output/"
mkdir $OUTPUT_PATH
OUTPUT_PATH=$(abspath $OUTPUT_PATH)

ELEMENTARY_PHENOTYPES_FILE="none"
COMPLEX_PHENOTYPES_FILE="none"
if [[ "$COMPUTATIONAL_WORKFLOW" = "Multiplexed IF diffusion" || "$COMPUTATIONAL_WORKFLOW" = "Multiplexed IF phenotype proximity" || "$COMPUTATIONAL_WORKFLOW" = "Multiplexed IF front proximity" || "$COMPUTATIONAL_WORKFLOW" = "Multiplexed IF density" ]];
then
    prompt_str="Enter the file containing metadata for the channels/observed phenotypes: "
    printf "$yellow$prompt_str$reset"
    while [[ "$ELEMENTARY_PHENOTYPES_FILE" = "none" || "$ELEMENTARY_PHENOTYPES_FILE" = "" ]];
    do
        read -e ELEMENTARY_PHENOTYPES_FILE
    done
    ELEMENTARY_PHENOTYPES_FILE=$(abspath $ELEMENTARY_PHENOTYPES_FILE)
    printf "$cr$yellow$prompt_str$reset$green$ELEMENTARY_PHENOTYPES_FILE$reset\n"

    COMPLEX_PHENOTYPES_FILE=""
    prompt_str="Enter the file that lists composite phenotypes of interest: "
    printf "$yellow$prompt_str$reset"
    while [[ "$COMPLEX_PHENOTYPES_FILE" = "none" || "$COMPLEX_PHENOTYPES_FILE" = "" ]];
    do
        read -e COMPLEX_PHENOTYPES_FILE
    done
    COMPLEX_PHENOTYPES_FILE=$(abspath $COMPLEX_PHENOTYPES_FILE)
    printf "$cr$yellow$prompt_str$reset$green$COMPLEX_PHENOTYPES_FILE$reset\n"
fi

if [[ "$COMPUTATIONAL_WORKFLOW" = "Multiplexed IF phenotype proximity" ]] ;
then
    prompt_str="Balanced/symmetric analysis with respect to phenotype pairs? (y/N): "
    printf "$yellow$prompt_str$reset"
    read -e BALANCED
    if [[ ( "$BALANCED" == "Y" ) || ( "$BALANCED" == "y" ) ]];
    then
        BALANCED="True"
    fi
    if [[ ! "$BALANCED" == "True" ]];
    then
        BALANCED="False"
    fi
    printf "$cr$yellow$prompt_str$reset$green$BALANCED$reset\n"
else
    BALANCED="False"
fi

if [[ "$COMPUTATIONAL_WORKFLOW" = "Multiplexed IF density" ]] ;
then
    prompt_str="Use intensity weighting? (y/N): "
    printf "$yellow$prompt_str$reset"
    read -e USE_INTENSITIES
    if [[ ( "$USE_INTENSITIES" == "Y" ) || ( "$USE_INTENSITIES" == "y" ) ]];
    then
        USE_INTENSITIES="True"
    fi
    if [[ ! "$USE_INTENSITIES" == "True" ]];
    then
        USE_INTENSITIES="False"
    fi
    printf "$cr$yellow$prompt_str$reset$green$USE_INTENSITIES$reset\n"
else
    USE_INTENSITIES="False"
fi

if [[ "$COMPUTATIONAL_WORKFLOW" = "Multiplexed IF diffusion" ]] ;
then
    prompt_str="Save GraphML representation of diffusion distances for every phenotype mask? (Y/n): "
    printf "$yellow$prompt_str$reset"
    read -e SAVE_GRAPHML
    if [[ ( "$SAVE_GRAPHML" == "Y" ) || ( "$SAVE_GRAPHML" == "y" ) ]];
    then
        SAVE_GRAPHML="True"
    fi
    if [[ ! "$SAVE_GRAPHML" == "True" ]];
    then
        SAVE_GRAPHML="False"
    fi
    printf "$cr$yellow$prompt_str$reset$green$SAVE_GRAPHML$reset\n"
else
    SAVE_GRAPHML="False"    
fi

RUN_PLATFORM=""
prompt_str="Select runtime platform: (""$reset$cyan""lsf""$reset$magenta  local""$reset$yellow""): "
while [[ "$RUN_PLATFORM" != "lsf" && "$RUN_PLATFORM" != "local" ]];
do
    printf "$yellow$prompt_str$reset"
    read -e RUN_PLATFORM
    if [[ "$RUN_PLATFORM" = "" ]];
    then
        RUN_PLATFORM="lsf"
        echo
    fi

    if [[ "$RUN_PLATFORM" == "lsf" ]];
    then
        bsub_location=$(command -v bsub)
        if [[ "$bsub_location" == "" ]];
        then
            printf "$cyan""bsub""$reset$red"" command not found and is required to schedule LSF jobs. Choose runtime platform ""$reset$magenta""local""$reset\n"
            RUN_PLATFORM=""
        fi
    fi
done && printf "$cr$yellow$prompt_str$reset$green$RUN_PLATFORM$reset\n"

EXCLUDED_HOSTNAME=""
prompt_str="Enter the name of a host name to exclude from deployment (e.g. a control node): "
printf "$yellow$prompt_str$reset"
while [[ "$EXCLUDED_HOSTNAME" = "" ]];
do
    read -e EXCLUDED_HOSTNAME
done
printf "$cr$yellow$prompt_str$reset$green$EXCLUDED_HOSTNAME$reset\n"
if [[ "$EXCLUDED_HOSTNAME" == "" ]]; then
    EXCLUDED_HOSTNAME="NO_EXCLUDED_HOSTNAME"
fi

SKIP_INTEGRITY_CHECK=""
prompt_str="Skip file integrity checks? (y/N): "
printf "$yellow$prompt_str$reset"
while [[ "$SKIP_INTEGRITY_CHECK" = "" ]];
do
    read -e SKIP_INTEGRITY_CHECK
done
printf "$cr$yellow$prompt_str$reset$green$SKIP_INTEGRITY_CHECK$reset\n"
if [[ "$SKIP_INTEGRITY_CHECK" == "n" || "$SKIP_INTEGRITY_CHECK" == "N" ]]; then
    SKIP_INTEGRITY_CHECK="False"
fi
if [[ ( "$SKIP_INTEGRITY_CHECK" == "Y" ) || ( "$SKIP_INTEGRITY_CHECK" == "y" ) ]]; then
    SKIP_INTEGRITY_CHECK="True"
fi

START_IMMEDIATELY=""
prompt_str="Schedule immediately? (""$reset$cyan""Y""$reset$magenta/n""$reset$yellow""): "
printf "$yellow$prompt_str$reset"
read -e START_IMMEDIATELY
if [[ "$START_IMMEDIATELY" = "" ]];
then
    START_IMMEDIATELY="Y"
    echo
fi
if [[ "$START_IMMEDIATELY" = "y" ]];
then
    START_IMMEDIATELY="Y"
fi
if [[ "$START_IMMEDIATELY" != "Y" ]];
then
    START_IMMEDIATELY="n"
fi
printf "$cr$yellow$prompt_str$reset$green$START_IMMEDIATELY$reset\n"

JOBS_PATH='jobs'
if [[ ! -d $JOBS_PATH ]] ;
then
    mkdir $JOBS_PATH
fi
JOBS_PATH=$(abspath $JOBS_PATH)

LOGS_PATH='logs'
if [[ ! -d $LOGS_PATH ]] ;
then
    mkdir $LOGS_PATH
fi
LOGS_PATH=$(abspath $LOGS_PATH)

SCHEDULERS_PATH='./'
SCHEDULERS_PATH=$(abspath $SCHEDULERS_PATH)

printf "$yellow""Job scripts will be written to $green$JOBS_PATH$reset\n"
printf "$yellow""Scheduler scripts will be written to ""$green$SCHEDULERS_PATH$reset\n"

spt-generate-jobs \
    --sif-file $SIF_PATH \
    --computational-workflow "$COMPUTATIONAL_WORKFLOW" \
    --input-path $INPUT_PATH \
    --outcomes-file $OUTCOMES_FILE \
    --output-path $OUTPUT_PATH \
    --jobs-path $JOBS_PATH \
    --logs-path $LOGS_PATH \
    --schedulers-path $SCHEDULERS_PATH \
    --file-manifest $FILE_MANIFEST \
    --runtime-platform $RUN_PLATFORM \
    --elementary-phenotypes-file $ELEMENTARY_PHENOTYPES_FILE \
    --complex-phenotypes-file $COMPLEX_PHENOTYPES_FILE \
    --excluded-hostname $EXCLUDED_HOSTNAME \
    --skip-integrity-check $SKIP_INTEGRITY_CHECK \
    --balanced $BALANCED \
    --use-intensities $USE_INTENSITIES \
    --save-graphml $SAVE_GRAPHML \

chmod +x *.sh

if [[ "$START_IMMEDIATELY" == "Y" ]];
then
    schedule_scripts
fi
