#!/bin/bash

if [[ $# != 4 ]]; then
  echo
  echo "Arguments passed was $# (4 required)"
  echo "1st argument : properties file"
  echo "2nd argument : encryption key"
  echo "3rd argument : CSV file to process"
  echo "4th argument : CSV column delimiter"
  echo
  exit
fi

SOAP_JAR="callSoap.jar"
SOAP_KS="ldap.keystore"

if [ ! -f $SOAP_JAR ]; then
    echo "The $SOAP_JAR JAR file does not exist"
    exit
fi

if [ ! -f $1 ]; then
    echo "The $1 file does not exist"
    exit
fi

PROG_KS=$(cat $1 | grep "^SSL\\s*=" | awk -F= '{print $NF}')
PROG_KS=$(echo "${PROG_KS#[[:space:]]}")
PROG_KS=$(echo "${PROG_KS%[[:space:]]}")
PROG_KS=$(echo $PROG_KS | tr '[:upper:]' '[:lower:]')

if [[ "$PROG_KS" = true ]] && [[ ! -f $SOAP_KS ]]; then
  echo "SSL is defined as $PROG_KS in $1 : $SOAP_KS file does not exist"
  exit
fi

if ! [[ $2 =~ ^[0-9a-zA-Z]{16}$ ]]; then
  echo "The encryption key must have a length of 16"
  exit
fi

if [ ! -f $3 ]; then
  echo "The $3 file does not exist"
  exit
fi

PROG_DELIM=$(cat $1 | grep ARGUMENT_DELIMITER | awk -F= '{print $NF}')
PROG_DELIM=$(echo "${PROG_DELIM#[[:space:]]}")
PROG_DELIM=$(echo "${PROG_DELIM%[[:space:]]}")

if [ $PROG_DELIM = $4 ]; then
    echo "The $4 delimiter is invalid (also specified in the $1 file)"
  exit
fi

JRE="java"

echo -n "Where is java? Press enter to use \"$JRE\", \"v\" to merely verify the CSV file, or enter a Java location: "
read userInput
if [[ -n "$userInput" ]]; then
    JRE=$userInput
fi

PROPS=$1
KEY=$2
FILE=$3
DELIMITER=$4

echo
echo "Properties file      : $PROPS"
echo "Encryption key       : $KEY"
echo "CSV file to process  : $FILE"
echo "CSV column delimiter : $DELIMITER"
echo "Java binary to use   : $JRE"
echo

read -r firstline < $FILE

tags=(${firstline//,/ })
LENGTH_TAGS=${#tags[@]}

echo "Replace tokens [ "${#tags[@]}" ] : "${tags[@]}

lines_error=()
lines_total=1
lines_read=0
lines_valid=0
lines_end_check="^.+"$DELIMITER"$"
soap_sent=0

while read LINE || [ -n "$LINE" ]; do
  LINE=$(echo "${LINE#[[:space:]]}")
  LINE=$(echo "${LINE%[[:space:]]}")
  if [[ $LINE =~ ^.+$ ]]; then
    valid=true
    pos=0

    IFS=$DELIMITER read -r -a valueArray <<< "$LINE"
    LENGTH_LINE=${#valueArray[@]}
    if [[ $LINE =~ $lines_end_check ]]; then
      LENGTH_LINE=$((LENGTH_LINE+1))
    fi

    for element in "${tags[@]}"; do
      value=${valueArray[$pos]}
      value=$(sed 's/^[[:space:]]*//' <<< "$value")
      value=$(echo "${value}" | sed -e 's/\ *$//g')
      if [[ $value =~ ^$ ]] || [[ $LENGTH_LINE != $LENGTH_TAGS ]]; then
        valid=false
      fi
      pos=$((pos+1))
    done

    if [ "$valid" = true ]; then
      echo "[ PASS : line "$((lines_total+1))" ]"
      lines_valid=$((lines_valid+1))
    else
      echo "[ FAIL : line "$((lines_total+1))" ]"
      this_error=$(echo "[ line "$((lines_total+1))" ] : $LINE")
      lines_error+=("$this_error")
    fi

    lines_read=$((lines_read+1))
  fi
  lines_total=$((lines_total+1))
done < <(tail -n +2 $FILE)

if [[ ${#lines_error[@]} -gt 0 ]]; then
  echo
  echo "## NUMBER OF VERIFICATION ERRORS WAS "$((lines_read-lines_valid))" ##"
  printf '%s\n' "${lines_error[@]}"
fi

echo
echo "Verification result : verified lines was "$lines_valid" of "$lines_read

if [[ $JRE = "v" || $lines_valid != $lines_read ]]; then
  echo
  exit
fi

while read LINE || [ -n "$LINE" ]; do
  LINE=$(echo "${LINE#[[:space:]]}")
  LINE=$(echo "${LINE%[[:space:]]}")
  if [[ $LINE =~ ^.+$ ]]; then
    pos=0
    param=""
    IFS=$DELIMITER read -r -a valueArray <<< "$LINE"
    for element in "${tags[@]}"; do
      value=${valueArray[$pos]}
      value=$(sed 's/^[[:space:]]*//' <<< "$value")
      value=$(echo "${value}" | sed -e 's/\ *$//g')
      param=$param"\"$element$PROG_DELIM$value"\"" "
      pos=$((pos+1))
    done

    cmd=($JRE -Djavax.net.ssl.trustStore=$SOAP_KS -jar $SOAP_JAR --key $KEY --props $PROPS --replace $param)
    result=$(eval ${cmd[@]})
    result=$(echo $result | tr -d '\n')
    verify=$(echo $result | sed -E 's/^(.+)(Exception|SOAP Document received: )(.+)$/\2\3/')

    if [[ ! "$result" == "$verify" ]] && [[ ! $verify =~ "HTTP" ]] && [[ ! $verify =~ "Exception" ]]; then
      soap_sent=$((soap_sent+1))
    fi

  fi
done < <(tail -n +2 $FILE)

echo
echo "Finished processing [ "$FILE" ] : lines processed was  "$lines_read
echo "Finished processing [ "$FILE" ] : successful calls was "$soap_sent