#!/usr/bin/env bash

#
# Copyright 2015-2019 Intel Corporation.
# This software and the related documents are Intel copyrighted materials, and your use of them 
# is governed by the express license under which they were provided to you ("License"). Unless the 
# License provides otherwise, you may not use, modify, copy, publish, distribute, disclose or 
# transmit this software or the related documents without Intel's prior written permission.
# 
# This software and the related documents are provided as is, with no express or implied warranties, 
# other than those that are expressly stated in the License.
# 
#


helpModule () {
  echo "This module runs a single query on a single stream"
  echo
  echo "Options:"
  echo -e "-d\tdatabase to use"
  echo -e "-h\tshow this help"
  echo
  echo "INTERNAL options:"
  echo -e "-q\tquery number to run (required)"
  echo -e "-D\tquery part to debug"
  echo -e "-p\tbenchmark phase to use"
  echo -e "-t\tstream number for query run"
  echo -e "-y\tfile with user defined query parameters"
  echo -e "-z\tfile with user defined engine settings"
}

runModule () {
  if ! runCmdWithErrorCheck initQueryEnv
  then
    return 1
  fi

  echo "==============================================="
  echo "Running query : $QUERY_NAME"
  echo "-----------------------------------------------"
  echo "benchmark phase: $BIG_BENCH_BENCHMARK_PHASE"
  echo "stream number  : $BIG_BENCH_STREAM_NUMBER"
  echo "user parameter file: $USER_QUERY_PARAMS_FILE"
  echo "user settings file : $USER_ENGINE_SETTINGS_FILE"
  if [ -n "$DEBUG_QUERY_PART" ]
  then
    echo "query part to debug: $DEBUG_QUERY_PART"
  fi
  echo "log: $LOG_FILE_NAME"
  echo "==============================================="

  ### Checking required folder: logs/; tmp/; result/ if they exist, create them and set permissions

  echo "checking existence of local: $BIG_BENCH_LOGS_DIR"
  if [ ! -d "$BIG_BENCH_LOGS_DIR" ]; then
    mkdir -p "$BIG_BENCH_LOGS_DIR"
  fi

  if [ ! -e "$LOG_FILE_NAME" ] ; then
      touch "$LOG_FILE_NAME"
  fi

  if [ ! -w "$LOG_FILE_NAME" ] ; then
      echo "ERROR: cannot write to: $LOG_FILE_NAME, no permission"
      return 1
  fi
  local LOG_FILE_EXEC_TIMES="${BIG_BENCH_LOGS_DIR}/times.csv"
  if [ ! -e "$LOG_FILE_EXEC_TIMES" ]
  then
    touch "$LOG_FILE_EXEC_TIMES"
    echo "STARTDATE_EPOCH|STOPDATE_EPOCH|DURATION_MS|STARTDATE|STOPDATE|DURATION|QUERY|SCALE_FACTOR|BENCHMARK_PHASE|STREAM|SUCCESSFUL|EXIT_CODE|HAS_RESULT|HDFS_SIZE" >> "${LOG_FILE_EXEC_TIMES}"
  fi

  if [ ! -w "$LOG_FILE_EXEC_TIMES" ]
  then
    echo "ERROR: cannot write to: $LOG_FILE_EXEC_TIMES, no permission"
    return 1
  fi

  #dont delete/recreate result and temp folders if query is in debug mode: exception: step 1 of debug
  if [ -z "$DEBUG_QUERY_PART" ] || [ $DEBUG_QUERY_PART -eq 1 ]
  then
    echo "creating/cleaning/set permissions for hdfs tmp and result folders for this query"

    local STARTDATE2="`date +%Y/%m/%d:%H:%M:%S`"
    local STARTDATE_EPOCH2="`date +%s`" # seconds since epoch

    #cannot run this hdfs commands in parallel, because they depend on each other and it would break error handling
    hadoop fs -rm -r -f -skipTrash "${RESULT_DIR}"
    hadoop fs -rm -r -f -skipTrash "${TEMP_DIR}"
    hadoop fs -mkdir -p "${RESULT_DIR}"
    hadoop fs -mkdir -p "${TEMP_DIR}"
    hadoop fs -chmod ugo+rwx "${BIG_BENCH_HDFS_ABSOLUTE_TEMP_DIR}"
    hadoop fs -chmod ugo+rwx "${BIG_BENCH_HDFS_ABSOLUTE_QUERY_RESULT_DIR}"
    hadoop fs -chmod ugo+rwx "${RESULT_DIR}"
    hadoop fs -chmod ugo+rwx "${TEMP_DIR}"

    local STOPDATE2="`date +%Y/%m/%d:%H:%M:%S`"
    local STOPDATE_EPOCH2="`date +%s`" # seconds since epoch
    local DIFF_s2=$(($STOPDATE_EPOCH2-$STARTDATE_EPOCH2))
    local DIFF_ms2=$(($DIFF_s2*1000))
    local DURATION2="$(($DIFF_s2 / 3600 ))h $((($DIFF_s2 % 3600) / 60))m $(($DIFF_s2 % 60))s"
    echo "Duration for hdfs prepare:  $DURATION2" 
  fi

  #################
  # exec query.
  #################
  
   # time measurement of execution
  local STARTDATE="`date +%Y/%m/%d:%H:%M:%S`"
  local STARTDATE_EPOCH="`date +%s`" # seconds since epoch
  # Run the main method implemented in the query's run.sh
  #Stderr is appended to stdout and both are written into logs/q??.log and to console
  "$QUERY_MAIN_METHOD" 2>&1 | tee -a "$LOG_FILE_NAME" 2>&1
  local QUERY_EXIT_CODE=${PIPESTATUS[0]}
  
  if [ "$QUERY_EXIT_CODE" -ne 0 ]
  then
    local successOrFail="FAILED"
  else
    local successOrFail="SUCCESS"
  fi
  
  local STOPDATE="`date +%Y/%m/%d:%H:%M:%S`"
  local STOPDATE_EPOCH="`date +%s`" # seconds since epoch
  local DIFF_s="$(($STOPDATE_EPOCH - $STARTDATE_EPOCH))"
  local DIFF_ms="$(($DIFF_s * 1000))"
  local DURATION="$(($DIFF_s / 3600 ))h $((($DIFF_s % 3600) / 60))m $(($DIFF_s % 60))s"

  #evaluate results
  local RESULT_FOLDER_HDFS_SIZE=`hadoop fs -du -s  $RESULT_DIR | cut -d ' ' -f 1`

  if [ "$RESULT_FOLDER_HDFS_SIZE" -gt 0 ]
  then
    local QUERY_HAS_RESULT="HAS_RESULT"
  else
    local QUERY_HAS_RESULT="EMPTY"
  fi

  # log query statistics to times.csv file
  echo "${STARTDATE_EPOCH}|${STOPDATE_EPOCH}|${DIFF_ms}|${STARTDATE}|${STOPDATE}|${DURATION}|${QUERY_NAME}|${BIG_BENCH_SCALE_FACTOR}|${BIG_BENCH_BENCHMARK_PHASE}|${BIG_BENCH_STREAM_NUMBER}|${successOrFail}|${QUERY_EXIT_CODE}|${QUERY_HAS_RESULT}|${RESULT_FOLDER_HDFS_SIZE}" >> ${LOG_FILE_EXEC_TIMES}

  # log query statistics to console and query log
  echo "======= $TABLE_PREFIX time =======" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "Start timestamp: $STARTDATE $STARTDATE_EPOCH" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "Stop  timestamp: $STOPDATE $STOPDATE_EPOCH" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "Duration:  $DURATION" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "${TABLE_PREFIX} ${successOrFail} exit code: ${QUERY_EXIT_CODE} " | tee -a "$LOG_FILE_NAME" 2>&1 
  echo "----- result -----" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "${QUERY_HAS_RESULT}  bytes: ${RESULT_FOLDER_HDFS_SIZE}" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "to display: hadoop fs -cat $RESULT_DIR/*" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "----- logs -----" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "time&status: ${LOG_FILE_EXEC_TIMES}" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "full log: $LOG_FILE_NAME" | tee -a "$LOG_FILE_NAME" 2>&1
  echo "=========================" | tee -a "$LOG_FILE_NAME" 2>&1

 return "${QUERY_EXIT_CODE}"
}
