#!/usr/bin/env bash

# Check for required environment variables
exit_code=0

if [ -z "$INFORMATICA_USER" ]; then
  echo "Required environment variable INFORMATICA_USER is not set, exiting."
  exit_code=1
fi

if [ -z "$INFORMATICA_PASSWORD" ]; then
  echo "Required environment variable INFORMATICA_PASSWORD is not set, exiting."
  exit_code=1
fi

# Region should be set in the image, because it is needed for file download during the build process
if [ -z "$REGION" ]; then
  echo "Required environment variable REGION is not set, exiting."
  exit_code=1
fi

[ "$exit_code" -eq 1 ] && exit $exit_code

## this wrapper takes care of running the agent and shutdown gracefully Under Docker
#set -x

# colors
red='\e[0;31m'
green='\e[0;32m'
yellow='\e[0;33m'
reset='\e[0m'

WORK_DIR=.
PID_FILE=$WORK_DIR/infaagentprocessid

#Colorized echo
echoRed() { echo -e "${red}$1${reset}"; }
echoGreen() { echo -e "${green}$1${reset}"; }
echoYellow() { echo -e "${yellow}$1${reset}"; }

# SIGUSR1-handler
my_handler() {
  echo "Stopped Wait Loop"
}

prep_term() {
  unset term_child_pid
  trap 'handle_term' TERM INT
  # kill the last background process, which is `tail -f /dev/null` and execute the specified handler
  trap 'kill ${!}; my_handler' SIGUSR1
  echo 'Termination Handler Ready'
}

handle_term() {
  echo "TERM Signal Received. Shutting Down PID $term_child_pid..."
  if [ -z "$(pgrep -F $PID_FILE)" ]; then
    echoRed "Process $term_child_pid not running";
    exit 143;
  else
    echoGreen "PID $term_child_pid found, shuting down..."
    ./infaagent shutdown
    echo "Secure Agent Stopped"
    exit 143; # 128 + 15 -- SIGTERM
  fi
}

set_json_log() {

  if [ ! -z ${JSON_LOG} ]; then

    # https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html

    # Replace the text line with a json formatted line.  This is ugly.
    find . -type f -name log4j.properties \
    -exec sed -i '/^log4j.appender.stdout.layout.ConversionPattern/c\log4j.appender.stdout.layout.ConversionPattern={"dateIso8601":"%d","timeZone":"%d{z}","priority":"%p","category":"%c","message":"%m"}%n' \
     {} \;

  fi

}

# Login to the API with the provided username and password and get the URL and session id
# so we can check the status of this agent.  Read results into Bash array

echo "Logging in to Informatica API"

json=$(curl -sS -H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "{\"username\":\"${INFORMATICA_USER}\",\"password\":\"${INFORMATICA_PASSWORD}\"}" \
"https://${REGION}.informaticacloud.com/ma/api/v2/user/login")

if [ -z "$json" ]; then
  echo "No result from API"
  exit 1
fi

status_code=$(jq -nr "${json}|.statusCode")

if [ -z "$status_code" ]; then
  echo "Error connecting to Informatica API"
  echo $json
  exit 1
fi

error_code=$(jq -nr "${json}|.error.code")

if [ -z "$error_code" ]; then
  echo "Error connecting to Informatica API: ${error_code}"
  echo $json
  exit 1
fi

result=($(jq -nr "${json}|.serverUrl, .icSessionId"))

if [ -z "$result" ]; then
  echo "Unknown error when querying the API, exiting"
  exit 1
fi

echo "Successfully logged into the API"

server_url=${result[0]}
ic_session_id=${result[1]}

if [ -z ${server_url+x} ]; then
  echo "No Server URL set"
  exit 1
fi

if [ -z ${ic_session_id+x} ]; then
  echo "No session id"
  exit 1
fi

# Check for the existance of infaagent.ini and see if it has been registered.

register=true
agent_id=$(grep -oPs '^InfaAgent.Id=\K.+' conf/infaagent.ini)

if [ -z "${agent_id}" ]; then
  echo "No agent id found, registering new agent"
else

  # If we find an agent_id, then query the Informatica API and
  # check the registered agent ID to see if it is running or not.
  # active seems to be set to true if it has been running recently
  # readyToRun means it is up and running

  echo "Checking the status of ${agent_id} using the agent API"

  result=($(curl -sS -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "icSessionId: ${ic_session_id}" \
  "${server_url}/api/v2/agent/${agent_id}" | jq -r '.active, .readyToRun, .name'))

  if [ -z "${result[0]}" ]; then

    echo "Unable to find agent_id, registering a new agent"

  elif [[ "${result[0]}" = "true" && "${result[1]}" = "true" ]]; then

    echo "Already exists a running agent with the id of ${agent_id}, registering a new agent"

  else
    #Not running, but exists.  This should be the default condition, in which case we would just run the agent
    register=false

  fi

fi

# set shutdown hooks and set the json log file if necessary
prep_term
set_json_log

# run application
./infaagent startup

# sleep to allow startup (probably should refactor to use inotify tools or somesuch)
sleep 10

if [ "$register" = true ]; then

  echo "Registering a new secure agent"

  # Get a token by calling the API
  token=$(curl -sS -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "icSessionId: ${ic_session_id}" \
  "${server_url}/api/v2/agent/installerInfo/linux64" | jq -r .installToken)

  if [ -z ${token+x} ]; then
    echo "Did not retrieve a token from Informatica, exiting"
    exit 1
  fi

  # Register this agent with the USER variable and the TOKEN
  ./consoleAgentManager.sh configureToken $INFORMATICA_USER $token | \
  grep -q fails && \
  echo "Unable to register agent" && \
  exit 2
  # export exit_code="$(grep -c 'Token is invalid' agentcore.log)" && \

fi

# Logout of informatica API
curl -sS -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "icSessionId: ${ic_session_id}" \
  -X POST \
  "${server_url}/api/v2/user/logout"

# get agent process id
term_child_pid=$(cat $PID_FILE)
echoGreen "Secure Agent Starting pid:$term_child_pid"


# wait until terminated
while true
do
  tail -f agentcore.log & wait ${!}
done
