#!/bin/sh

trap InstallationInterrupted 2


#This function checks which pipelines have an available Reflex workflow
#and stores in file "${dataset_dir}"/available_pipelines the following info:
#Pipeline  Version Data Pipeline-kit Demodataset
GetAvailablePipelines()
{
  cd "${tempdir}"

    silent_url="https://ftp.eso.org/pub/dfs/pipelines/repositories/${release_channel}/kit/reflex_cfg/reflex_${release_channel}.txt"

    $httpcommand "$silent_url" > /dev/null 2>&1

    if [ $? -ne 0 ]; then
      echo ERROR: Could not retrieve available pipelines.
      echo ERROR: Please make sure you have access to ESO webpages
      echo ERROR: Also, try with the latest version of install_esoreflex
      echo ERROR:       from https://www.eso.org/sci/software/pipelines/install_esoreflex
      echo ERROR: If problem persists, contact usd-help@eso.org
      Cleanup
      exit 1
    fi
    sort -k 1 reflex_${release_channel}.txt | uniq > available_pipelines_sorted
    \mv -f available_pipelines_sorted available_pipelines
    if [ ! -s available_pipelines ]
    then
      echo
      echo ERROR: No pipelines are available in this release channel
      Cleanup
      exit 1
    fi
    \rm -f "${tempdir}/index.html"
    \cp available_pipelines "${dataset_dir}"
}


#This function will show the available pipelines and their versions and 
#will prompt for the desired pipelines to be installed
GetPipelinesToInstall()
{
  cd "${tempdir}"
  echo ==================================================================
  echo The following list contains the latest available versions of
  echo demo data published by the VLT pipelines team
  echo Please specify ALL the pipelines you want to install their demo data.
  echo
  echo Please specify \'A\' to install all available pipelines demo data, or a 
  echo selection of pipelines by writing a space-separated list of the PipeIDs.
  echo 'PipeID    Instrument       Version                 '
  awk '{printf("%-9d %-16s %-22s   %-s\n",NR,$1,$2,$5)}' "${dataset_dir}"/available_pipelines
  echo
  while :
  do
    printf  "Input PipeIDs for pipelines to install [A]: " 
    read -r pipeline_numbers_to_install
    if [ -z "$pipeline_numbers_to_install" ] ; then
      pipeline_numbers_to_install="A"
    fi

    \rm -f pipelines_to_install
    number_pipes=`wc -l < ${dataset_dir}/available_pipelines`
    cat -n "${dataset_dir}"/available_pipelines | while read pipeid pipename pipever somethings
    do
      echo ${pipeid} ${pipename} ${pipever} ${pipeline_numbers_to_install} | awk -v number_pipes="$number_pipes" '{for(i=4; i<=NF; i++){if( $i != "A" && ( ( $i != $i + 0 ) ||  ( ( $i == $i + 0 ) && ( ( $i < 1 ) || ( $i > number_pipes ) ) ) ) ) {print "WARNING: Invalid input. Enter numbers in the valid range or A."};  if( $i == $1 || $i == "A" ){printf("%s   %s\n", $2, $3)}}}' >> pipelines_to_install
    done

    grep WARNING pipelines_to_install | head -1
    if grep WARNING pipelines_to_install > /dev/null
    then
      echo
    else
      if [ -s pipelines_to_install ]
      then
        break
      else
        echo 
        echo WARNING: No pipeline has been specified. Please try again
        echo
      fi
    fi
  done
  sort -k 1 pipelines_to_install | uniq > pipelines_to_install_sorted
  \mv -f pipelines_to_install_sorted pipelines_to_install

  if [ -f "${installation_dir}/etc/vltpipe_reflex_install/installed_pipelines" ]
  then
    sort -k 1 "${installation_dir}/etc/vltpipe_reflex_install/installed_pipelines" > installed_pipelines_sorted
    join -j 1 -v 2 pipelines_to_install installed_pipelines_sorted > pipelines_to_remove
    local lines_pipe_remove=`wc -l < pipelines_to_remove`
    if [ $lines_pipe_remove -eq 0 ]
    then
      \rm -f pipelines_to_remove
    fi
    diff pipelines_to_install installed_pipelines_sorted > difference_installed_pipelines
    local lines_diff_inst=`wc -l < difference_installed_pipelines`
    if [ $lines_diff_inst -eq 0 ]
    then
      \rm -f pipelines_to_install
    fi
  fi

  echo
}

#This function will select the desired demo data to be installed
GetPipelineDemoDataToInstall()
{
  cd "${tempdir}"
  echo ==================================================================
  echo Pipeline workflows are distributed with demo data that allows
  echo to run the workflow right away.
  echo Please specify \'A\' to install all available demo data \(recommended\), 
  echo \'None\' to not install any demo data, or a
  echo selection of demo data by writing a space-separated list of the PipeIDs.
  echo 'PipeID    Instrument       Version'
  awk '{printf("%-9d %-16s %-22s\n",NR,$1,$2)}' pipelines_to_install
  echo
  while :
  do
    printf  "Input PipeIDs for demo data to install [A]: " 
    read -r pipedata_numbers_to_install
    if [ -z "$pipedata_numbers_to_install" ] ; then
      pipedata_numbers_to_install="A"
    fi

    \rm -f pipelines_to_install
    number_pipe_data=`wc -l < pipelines_to_install`
    cat -n pipelines_to_install | while read pipeid pipename pipever somethings
    do
      echo ${pipeid} ${pipename} ${pipever} ${pipedata_numbers_to_install} | awk -v number_pipe_data="$number_pipe_data" '{for(i=4; i<=NF; i++){if( $i != "None" && $i != "A" && ( ( $i != $i + 0 ) ||  ( ( $i == $i + 0 ) && ( ( $i < 1 ) || ( $i > number_pipe_data ) ) ) ) ) {print "WARNING: Invalid input. Enter numbers in the valid range, None or A."};  if( $i == $1 || $i == "A" ){printf("%s   %s\n", $2, $3)}}}' >> pipedata_to_install
    done

    grep WARNING pipelines_to_install | head -1
    if grep WARNING pipelines_to_install > /dev/null
    then
      echo
    else
      break
    fi
  done

  echo
}



#Present a summary of the steps to be done and will exit if not confirmed
ConfirmInstallation()
{
  cd "${tempdir}"
  echo ==================================================================
  if [ -f pipelines_to_install ] ; then
    echo The following demo data sets will be downloaded:
    cat pipelines_to_install
  else
    echo No demo dataset will be installed.
  fi
  echo
  echo
  echo ==================================================================    


  echo "The following directory will be used:"
  echo "Directory for demo datasets:                " $dataset_dir
  echo

  printf "Please confirm to proceed [Y/n]: " 
  read -r proceed
  proceed=`echo $proceed | tr '[:upper:]' '[:lower:]'`
  if [ "x$proceed" = "xn" ] ; then
    echo Aborting
    Cleanup
    exit 1
  fi
    
  echo WARNING: Please, do not interrupt the download from this point on
  echo WARNING: Otherwise you might get a broken installation
}

DownloadDemoData()
{
  if [ -f "${tempdir}/pipelines_to_install" ] ; then

    
    echo Downloading pipeline demo data
    while read pipename pipeversion 
    do
      if grep "^$pipename " "${tempdir}/pipelines_to_install" > /dev/null 2>&1 ; then
        echo Downloading ${pipename} data
        local pipedata=`grep "^${pipename} " "${dataset_dir}"/available_pipelines | awk '{print $4}' `
        local pipe_data_name=`echo $pipedata  | awk -F'/' '{print $(NF)}' `
        local pipe_name=`echo $pipe_data_name | awk -F'-' '{print $1}' `
        ${httpcommand} "$pipedata"
        if [ $? -ne 0 ]; then
          echo ERROR: Could not retrieve pipeline data $pipedata.
          echo ERROR: Check disk space or permissions
          Cleanup
          exit 1
        fi
        
        echo Installing ${pipename} data
        file $pipe_data_name  > "${tempdir}/file_tmp" 2>&1
        grep gzip "${tempdir}/file_tmp" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
          compress_opt=z
        fi
        grep bzip2 "${tempdir}/file_tmp" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
          compress_opt=j
        fi
        # Both lower and upper case needs to be handled since the output string
        # is declared differently with the 'file' command on Mac OSX and Linux.
        grep xz "${tempdir}/file_tmp" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
          compress_opt=J
        fi
        grep XZ "${tempdir}/file_tmp" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
          compress_opt=J
        fi
        if [ ! -d "${dataset_dir}/${pipe_name}" ] ; then
          CreateDirectory "${dataset_dir}/${pipe_name}"
        fi
        tar -${compress_opt} -xf $pipe_data_name -C "${dataset_dir}/${pipe_name}" > /dev/null 2>&1
        if [ $? -ne 0 ]; then
          echo WARNING: Could not install pipeline data. Check disk space or permissions
          echo WARNING: Installation will continue without this data being installed
        fi
        \rm -rf "${tempdir}/file_tmp"

      fi
    done < "${tempdir}/pipelines_to_install"
    echo Download of pipeline data succeeded.
    \rm "${dataset_dir}/available_pipelines"
  fi
}

#Creates a temporary unique directory and stores its name in the
#variable name passed as first argument
MakeTempDir()
{
  local _tempdir=$1
  mytempdir=$(mktemp -d "$dataset_dir"/install_demodata_temp.XXXXXXXXXXXX) || { echo "ERROR creating a temporary directory" >&2; Cleanup; exit 1; }
  eval $_tempdir="'$mytempdir'"
}

#Remove completely the temporary directory.
RemoveTempDir()
{
  test -n "$tempdir" && \rm -rf "$tempdir"
}

GetScriptOptions()
{
  #Default release channel          
  release_channel=stable
  while getopts "d:i:s:r:h" option_name; do
    case "$option_name" in
      s) dataset_dir="$OPTARG";;
      r) release_channel="$OPTARG";;
      h) PrintUsageAndExit;;
      [?]) PrintUsageAndExit ;;
    esac
  done
}

PrintUsageAndExit()
{
  version=`echo \$Revision: 1 $ | cut -f 2 -d' '`
  echo This is the $0 script to download ESO VLT pipelines demodata. Version $version
  echo Please follow the instructions that appear in the screen.
  echo
  echo "Usage: $0 [-s DATA_DIR] [-h]"
  echo
  echo "       -s DATA_DIR      The directory where the demo data will be saved."

  echo
  echo " Example: download_demodata  -s d_dir"

  Cleanup
  exit 1
}

#Get the name of the directories
GetConfigDirectories()
{   

  if [ -z "$dataset_dir" ] ; then
    printf "Input directory for installation of demo datasets (variable size) [$HOME/reflex_rawdata]: " 
    read -r dataset_dir
    if [ -z "$dataset_dir" ] ; then
      dataset_dir="$HOME/reflex_rawdata"
    fi
  fi

  if [ ! -d "${dataset_dir}" ] ; then
    CreateDirectory "${dataset_dir}"
  fi
  local base_dir=$PWD
  cd "${base_dir}"
  cd "${dataset_dir}"
  dataset_dir=${PWD}
    
  echo Using the following directory configuration
  echo Demo dataset directory: ${dataset_dir}
  echo
}

GetReleaseChannel()
{
  if [ "$release_channel" != "stable" ] &&  [ "$release_channel" != "testing" ] &&  [ "$release_channel" != "devel" ] &&  [ "$release_channel" != "legacy" ] ; then
    echo Unknown release channel $release_channel
    Cleanup
    exit 1
  fi 
  if [ "$release_channel" != "stable" ] ; then
    echo Using release channel $release_channel
  fi
}

CreateDirectory()
{
  echo "Creating dir '$1'"
  mkdir -p "$1" > /dev/null 2> /dev/null
  retval=$?
  if [ $retval -ne 0 ]; then
    echo ERROR: Could not create dir $1. Verify path or permissions
    Cleanup
    exit 1
  fi
}

#Check if a command is in the path
CheckCommandExist()
{
  exec_com=$1
  command -v $exec_com > /dev/null 2> /dev/null
  local retval=$?
  if [ $retval -ne 0 ]; then
    echo ERROR: $exec_com is not installed in your system.
    Cleanup
    exit 1
  fi
}

#Check that the needed programas are in the path
CheckTextUtils()
{
  CheckCommandExist awk
  CheckCommandExist tr
  CheckCommandExist cat
  CheckCommandExist sed
  CheckCommandExist grep
  CheckCommandExist mkdir
  CheckCommandExist rm
  CheckCommandExist basename
}

#Get the command used to retrieve web pages. It can be wget or curl
GetHttpCommand()
{
  local _httpcommand=$1
  command -v wget > /dev/null 2> /dev/null
  retval=$?
  if [ $retval -ne 0 ]; then
    command -v curl > /dev/null 2> /dev/null
    retval=$?
    if [ $retval -ne 0 ]; then
      echo ERROR: Neither wget or curl are installed. Please install them.
      Cleanup
      exit 1
    else
      local myhttpcommand='curl -O -L -C -'
    fi
  else
    local myhttpcommand='wget -c'
  fi
  eval $_httpcommand="'$myhttpcommand'"
}

PrintWelcome()
{
  echo ========================================================================
  echo "  Welcome to the installation script for ESO pipelines Demo Data "
  echo ========================================================================
}

Cleanup()
{
  RemoveTempDir
}

InstallationInterrupted()
{
  echo
  echo Installation interrupted
  Cleanup
  exit 1
}

PrintWelcome
GetScriptOptions $@
GetConfigDirectories
GetReleaseChannel
MakeTempDir tempdir
GetHttpCommand httpcommand
#CheckForNewerScriptVersion
CheckTextUtils
GetAvailablePipelines
GetPipelinesToInstall
ConfirmInstallation
DownloadDemoData
Cleanup
exit
