#!/bin/bash

LOG_DIR="${REPORTS_DIR}/"
LOG_NAME="monitor_status"
LOG_EXT=".yaml"
LOG_FILE="${LOG_DIR}${LOG_NAME}${LOG_EXT}"
STATUS_VALUES=("pass" "fail")
REASON_VALUES=("defect" "config" "findings" "pass")

job_name="${LOG_NAME}"
status_file="${LOG_FILE}"
status=""
reason=""
log=""

function help_message() {
  IFS="|"
  echo "Usage: $0 [-h] [-s arg] [-r arg] [-l arg] [-f arg] [-j arg]" >&2
  echo "  -h  Display this message" >&2
  echo "  -s  Job status with value from (${STATUS_VALUES[*]})" >&2
  echo "  -r  Job reason with value from (${REASON_VALUES[*]})" >&2
  echo "  -l  Log message appended to list" >&2
  echo "  -f  Path to log file, current value: ${LOG_DIR}" >&2
  echo "  -j  Job name for status file creation, current value: ${LOG_NAME}" >&2
  echo "      File extension for log file: ${LOG_EXT}" >&2
}

function error_message() {
    echo "$1" >&2
    exit 1
}

function check_string_in_list() {
  local string="$1"
  local list=("${@:2}")

  for value in "${list[@]}"; do
    if [[ "$string" == "$value" ]]; then
      return 1
    fi
  done

  return 0
}

USE_YQ=
if command -v yq 2>&1 >/dev/null; then
  USE_YQ="true"
fi

while getopts :hj:s:r:l:f: flag
do 
  case "${flag}" in 
    h)
      help_message
      exit 0
      ;;
    s)
      status=${OPTARG}
      if check_string_in_list "$status" "${STATUS_VALUES[@]}"; then
        error_message "Status value not in (${STATUS_VALUES[*]})"
      fi 
      ;;
    r)
      reason=${OPTARG}
      if check_string_in_list "$reason" "${REASON_VALUES[@]}"; then
        error_message "Reason value not in (${REASON_VALUES[*]})"
      fi
      ;;
    l)
      log=${OPTARG}
      ;;
    j)
      job_name=${OPTARG}
      status_file="${LOG_DIR}${job_name}${LOG_EXT}"
      ;;
    f)
      LOG_FILE=${OPTARG}
      ;;
    :)
      echo "Option -${OPTARG} requires an argument." >&2
      echo ""
      help_message
      exit 1
      ;;
    ?)
      echo "Invalid option: -${OPTARG}." >&2
      echo ""
      help_message
      exit 1
      ;;
  esac
done

if [ -f "$status_file" ]; then
  if [ -n "$status" ]; then
    if [ -n "$USE_YQ" ]; then
      yq -Yi ".status=\"$status\"" "$status_file"
    else
      tmpfile=$(mktemp)
      cp "$status_file" "$tmpfile"
      awk "{sub(/status: .*/,\"status: ${status}\"); print}" "$tmpfile" > "$status_file"
      rm "$tmpfile"
    fi
  fi 

  if [ -n "$reason" ]; then
    if [ -n "$USE_YQ" ]; then
      yq -Yi ".reason=\"$reason\"" "$status_file"
    else
      tmpfile=$(mktemp)
      cp "$status_file" "$tmpfile"
      awk "{sub(/reason: .*/,\"reason: ${reason}\"); print}" "$tmpfile" > "$status_file"
      rm "$tmpfile"
    fi
  fi 
else
  if [ -z "$status" ]; then
    error_message "Status code is required from (${STATUS_VALUES[*]}) during initial log creation"
  fi 

  if [ -z "$reason" ]; then
    error_message "Reason code is required from (${REASON_VALUES[*]}) during initial log creation"
  fi 

  cat <<EOF > "$status_file"
status: "$status"
reason: "$reason"
log:
EOF
fi

if [ -n "$log" ]; then
  if [ -f "$status_file" ]; then
    echo "  - \"${log}\"" >> "$status_file"
  else 
    error_message "No log file exists (${status_file}) to append log message"
  fi 
fi 

exit 0
