#!/usr/bin/env bash

SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
SUITE=$(caller)
SUITE=$(basename "${SUITE}" .sh )

SELENIUM_DOCKER_IMAGE=selenium/standalone-chrome:103.0
UAA_DOCKER_IMAGE=cloudfoundry/uaa:75.21.0
KEYCLOAK_DOCKER_IMAGE=quay.io/keycloak/keycloak:20.0
HTTPD_DOCKER_IMAGE=httpd:latest
PADDING=""
declare -a REQUIRED_COMPONENTS

BIN_DIR=$(realpath ${SCRIPT}/../bin)
LOGS=${SCRIPT}/../logs/${SUITE}
SCREENS=${SCRIPT}/../screens/${SUITE}
CONF_DIR=/tmp/selenium/${SUITE}
ENV_FILE=$CONF_DIR/.env

parse_arguments() {
  if [[ "$#" -gt 0 ]]
  then
    if [[ "$1" == "start-rabbitmq" ]]
    then
      echo "start-rabbitmq"
    elif [[ "$1" == "start-others" ]]
      then
      echo "start-others"
    elif [[ "$1" == "stop-others" ]]
      then
      echo "stop-others"
    elif [[ "$1" == "test" ]]
      then
      echo "test $2"
    fi
  else
    echo "run"
  fi
}

COMMAND=$(parse_arguments $@)

tabs 4

print() {
  echo -e "${PADDING}$1"
}

begin() {
  print "\n$@"
  PADDING="${PADDING}\t"
}
end() {
  PADDING=`echo $PADDING | rev | cut -c 4- | rev`
  print "$@"
}
ensure_docker_network() {
  begin "Ensuring $DOCKER_NETWORK network ..."
  if [ ! "$(docker network ls | grep $DOCKER_NETWORK)" ]; then
    print "> DOCKER_NETWORK: $DOCKER_NETWORK created"
    docker network create $DOCKER_NETWORK
  fi
  end "$DOCKER_NETWORK network exists"
}
init_suite() {
  TEST_DIR=$(realpath ${SCRIPT}/../test)
  TEST_CASES_DIR=$(realpath ${TEST_DIR}${TEST_CASES_PATH:?"missing TEST_CASES_PATH"})
  if [ -z "${TEST_CONFIG_PATH}" ]; then TEST_CONFIG_DIR=$TEST_CASES_DIR
  else TEST_CONFIG_DIR=$(realpath ${TEST_DIR}${TEST_CONFIG_PATH})
  fi
  DOCKER_NETWORK=${DOCKER_NETWORK:-rabbitmq_net}

  begin "Initializing suite $SUITE ..."
  print "> REQUIRED_COMPONENTS: ${REQUIRED_COMPONENTS[*]}"
  print "> TEST_CASES_DIR: ${TEST_CASES_DIR} "
  print "> TEST_CONFIG_DIR: ${TEST_CONFIG_DIR} "
  print "> DOCKER_NETWORK: ${DOCKER_NETWORK} "
  print "> PROFILES: ${PROFILES} "
  print "> ENV_FILE: ${ENV_FILE} "
  print "> COMMAND: ${COMMAND}"
  end "Initialized suite ..."
}

build_mocha_image() {
  begin "Ensuring mocha-test image ..."
  if [[ "$(docker images -q mocha-test 2> /dev/null)" == "" ]]; then
    docker build -t mocha-test  --target test $SCRIPT/..
    print "> Built docker image"
  fi
  end "mocha-test image exists"
}

start_selenium() {
  begin "Starting selenium  ..."

  print "> SELENIUM_DOCKER_IMAGE: ${SELENIUM_DOCKER_IMAGE}"
  kill_container_if_exist selenium

  docker run \
    --detach \
    --name selenium \
    --net ${DOCKER_NETWORK} \
    -p 4444:4444 \
    --shm-size=2g \
    ${SELENIUM_DOCKER_IMAGE}

  wait_for_message selenium "Started Selenium Standalone"
  end "Selenium ready"
}

kill_container_if_exist() {
  docker stop $1 &> /dev/null || true && docker rm $1 &> /dev/null || true
}
wait_for_message() {
  attemps_left=10
  while ! docker logs $1 | grep -q "$2";
  do
      sleep 5
      print "Waiting 5sec for $1 to start ($attemps_left attempts left )..."
      ((attemps_left--))
      if [[ "$attemps_left" -lt 1 ]]; then
        print "Timed out waiting"
        exit 1
      fi
  done
}

init_rabbitmq() {
  RABBITMQ_CONFIG_DIR=${TEST_CONFIG_DIR}
  RABBITMQ_DOCKER_IMAGE=${RABBITMQ_DOCKER_IMAGE:-rabbitmq}

  print "> RABBITMQ_CONFIG_DIR: ${RABBITMQ_CONFIG_DIR}"
  print "> RABBITMQ_DOCKER_IMAGE: ${RABBITMQ_DOCKER_IMAGE}"
  [[ -z "${OAUTH_SIGNING_KEY_PATH}" ]] || print "> OAUTH_SIGNING_KEY_PATH: ${OAUTH_SIGNING_KEY_PATH}"

}
start_rabbitmq() {
  if [[ "$PROFILES" == *"docker"* ]]; then
    start_docker_rabbitmq
  else
    start_local_rabbitmq
  fi
}

start_local_rabbitmq() {
  begin "Starting rabbitmq ..."

  init_rabbitmq


  RABBITMQ_SERVER_ROOT=$(realpath $TEST_DIR/../../../../)
  MOUNT_RABBITMQ_CONF="/etc/rabbitmq/rabbitmq.conf"


  RABBITMQ_TEST_DIR="${RABBITMQ_CONFIG_DIR}" ${BIN_DIR}/gen-rabbitmq-conf ${RABBITMQ_CONFIG_DIR} $ENV_FILE /tmp$MOUNT_RABBITMQ_CONF
  print "> EFFECTIVE RABBITMQ_CONFIG_FILE: /tmp$MOUNT_RABBITMQ_CONF"
  print "> RABBITMQ_TEST_DIR: ${RABBITMQ_CONFIG_DIR}"

	gmake --directory=${RABBITMQ_SERVER_ROOT} run-broker \
		RABBITMQ_ENABLED_PLUGINS_FILE=${RABBITMQ_CONFIG_DIR}/enabled_plugins \
		RABBITMQ_CONFIG_FILE=/tmp$MOUNT_RABBITMQ_CONF

}
start_docker_rabbitmq() {
  begin "Starting rabbitmq in docker ..."

  init_rabbitmq
  kill_container_if_exist rabbitmq

  mkdir -p $CONF_DIR/rabbitmq
  MOUNT_RABBITMQ_CONF="/etc/rabbitmq/rabbitmq.conf"
  RABBITMQ_TEST_DIR="/var/rabbitmq" ${BIN_DIR}/gen-rabbitmq-conf ${RABBITMQ_CONFIG_DIR} $ENV_FILE $CONF_DIR/rabbitmq/rabbitmq.conf
  print "> EFFECTIVE RABBITMQ_CONFIG_FILE: $CONF_DIR/rabbitmq/rabbitmq.conf"
  print "> RABBITMQ_TEST_DIR: /var/rabbitmq"

  docker run \
    --detach \
    --name rabbitmq \
    --net ${DOCKER_NETWORK} \
    -p 15672:15672 -p 5672:5672 \
    -v ${RABBITMQ_CONFIG_DIR}/logging.conf:/etc/rabbitmq/conf.d/logging.conf:ro \
    -v $CONF_DIR/rabbitmq/rabbitmq.conf:${MOUNT_RABBITMQ_CONF}:ro \
    -v ${RABBITMQ_CONFIG_DIR}/enabled_plugins:/etc/rabbitmq/enabled_plugins \
    -v ${TEST_DIR}/${OAUTH_SIGNING_KEY_PATH}:/config \
    -v ${RABBITMQ_CONFIG_DIR}/imports:/var/rabbitmq/imports \
    ${RABBITMQ_DOCKER_IMAGE}

  wait_for_message rabbitmq "Server startup complete"
  end "RabbitMQ ready"
}
init_uaa() {
  UAA_CONFIG_PATH=${UAA_CONFIG_PATH:-oauth/uaa}
  UAA_CONFIG_DIR=$(realpath ${TEST_DIR}/${UAA_CONFIG_PATH})

  print "> UAA_CONFIG_DIR: ${UAA_CONFIG_DIR}"
  print "> UAA_URL: ${UAA_URL}"
  print "> UAA_DOCKER_IMAGE: ${UAA_DOCKER_IMAGE}"
}
start_uaa() {
  begin "Starting UAA ..."

  init_uaa
  kill_container_if_exist uaa

  MOUNT_UAA_CONF_DIR=$CONF_DIR/uaa

  mkdir -p $MOUNT_UAA_CONF_DIR
  cp ${UAA_CONFIG_DIR}/* $MOUNT_UAA_CONF_DIR
  ${BIN_DIR}/gen-uaa-yml ${UAA_CONFIG_DIR} $ENV_FILE $MOUNT_UAA_CONF_DIR/uaa.yml
  print "> EFFECTIVE UAA_CONFIG_FILE: $MOUNT_UAA_CONF_DIR/uaa.yml"

  docker run \
    --detach \
    --name uaa \
    --net ${DOCKER_NETWORK} \
    --publish 8080:8080 \
    --mount "type=bind,source=$MOUNT_UAA_CONF_DIR,target=/uaa" \
    --env UAA_CONFIG_PATH="/uaa" \
    --env JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom" \
    ${UAA_DOCKER_IMAGE}

  wait_for_oidc_endpoint uaa $UAA_URL
  end "UAA is ready"
}
init_keycloak() {
  KEYCLOAK_CONFIG_PATH=${KEYCLOAK_CONFIG_PATH:-oauth/keycloak}
  KEYCLOAK_CONFIG_DIR=$(realpath ${TEST_DIR}/${KEYCLOAK_CONFIG_PATH})
  KEYCLOAK_URL=${OAUTH_PROVIDER_URL}

  print "> KEYCLOAK_CONFIG_DIR: ${KEYCLOAK_CONFIG_DIR}"
  print "> KEYCLOAK_URL: ${KEYCLOAK_URL}"
  print "> KEYCLOAK_DOCKER_IMAGE: ${KEYCLOAK_DOCKER_IMAGE}"
}
start_keycloak() {
  begin "Starting keycloak ..."

  init_keycloak
  kill_container_if_exist keycloak

  MOUNT_KEYCLOAK_CONF_DIR=$CONF_DIR/keycloak

  mkdir -p $MOUNT_KEYCLOAK_CONF_DIR
  ${BIN_DIR}/gen-keycloak-json ${KEYCLOAK_CONFIG_DIR} $ENV_FILE $MOUNT_KEYCLOAK_CONF_DIR/test-realm.json
  print "> EFFECTIVE KEYCLOAK_CONFIG_FILE: $MOUNT_KEYCLOAK_CONF_DIR/test-realm.json"
  cp ${KEYCLOAK_CONFIG_DIR}/*.pem $MOUNT_KEYCLOAK_CONF_DIR

  docker run \
		--detach \
		--name keycloak \
    --net ${DOCKER_NETWORK} \
		--publish 8080:8080 \
    --publish 8443:8443 \
		--env KEYCLOAK_ADMIN=admin \
		--env KEYCLOAK_ADMIN_PASSWORD=admin \
		--mount type=bind,source=${MOUNT_KEYCLOAK_CONF_DIR},target=/opt/keycloak/data/import/ \
		${KEYCLOAK_DOCKER_IMAGE} start-dev --import-realm \
    --https-certificate-file=/opt/keycloak/data/import/server_localhost_certificate.pem \
    --https-certificate-key-file=/opt/keycloak/data/import/server_localhost_key.pem

  wait_for_oidc_endpoint keycloak $KEYCLOAK_URL
  end "Keycloak is ready"
}
wait_for_oidc_endpoint() {
  NAME=$1
  BASE_URL=$2
  if [[ $BASE_URL == *"localhost"** ]]; then
    wait_for_oidc_endpoint_local $NAME $BASE_URL
  else
    wait_for_oidc_endpoint_docker $NAME $BASE_URL
  fi
}
wait_for_oidc_endpoint_local() {
  NAME=$1
  BASE_URL=$2

  max_retry=10
  counter=0
  print "Waiting for OIDC discovery endpoint $NAME ... (BASE_URL: $BASE_URL)"
  until (curl -L --fail ${BASE_URL}/.well-known/openid-configuration >/dev/null 2>&1)
  do
    sleep 5
    [[ counter -eq $max_retry ]] && print "Failed!" && exit 1
    print "Trying again. Try #$counter"
    ((counter++))
  done
  sleep 20
}
wait_for_oidc_endpoint_docker() {
  NAME=$1
  BASE_URL=$2

  max_retry=10
  counter=0
  print "Waiting for OIDC discovery endpoint $NAME ... (BASE_URL: $BASE_URL)"
  until (docker run --net ${DOCKER_NETWORK} --rm curlimages/curl:7.85.0 -L --fail ${BASE_URL}/.well-known/openid-configuration >/dev/null 2>&1)
  do
    sleep 5
    [[ counter -eq $max_retry ]] && print "Failed!" && exit 1
    print "Trying again. Try #$counter"
    ((counter++))
  done
  sleep 20
}
calculate_rabbitmq_url() {
  echo "${RABBITMQ_SCHEME:-http}://$1${PUBLIC_RABBITMQ_PATH:-$RABBITMQ_PATH}"
}
init_fakeportal() {
  FAKEPORTAL_URL=${FAKEPORTAL_URL:-http://fakeportal:3000}
  FAKEPORTAL_DIR=${SCRIPT}/../fakeportal
  CLIENT_ID="${CLIENT_ID:-rabbit_idp_user}"
  CLIENT_SECRET="${CLIENT_SECRET:-rabbit_idp_user}"
  RABBITMQ_HOST=${RABBITMQ_HOST:-proxy:9090}
  RABBITMQ_HOST_FOR_FAKEPORTAL=${RABBITMQ_HOST_FOR_FAKEPORTAL:-rabbitmq:15672}

  RABBITMQ_URL=$(calculate_rabbitmq_url $RABBITMQ_HOST)
  RABBITMQ_URL_FOR_FAKEPORTAL=$(calculate_rabbitmq_url $RABBITMQ_HOST_FOR_FAKEPORTAL)

  print "> FAKEPORTAL_URL: ${FAKEPORTAL_URL}"
  print "> UAA_URL_FOR_FAKEPORTAL: ${UAA_URL_FOR_FAKEPORTAL}"
  print "> RABBITMQ_HOST_FOR_FAKEPORTAL: ${RABBITMQ_HOST_FOR_FAKEPORTAL}"
  print "> RABBITMQ_HOST: ${RABBITMQ_HOST}"
  print "> CLIENT_ID: ${CLIENT_ID}"
  print "> CLIENT_SECRET: ${CLIENT_SECRET}"
  print "> RABBITMQ_URL: ${RABBITMQ_URL}"
}
start_fakeportal() {
  begin "Starting fakeportal ..."

  init_fakeportal
  kill_container_if_exist fakeportal

  docker run \
    --detach \
    --name fakeportal \
    --net ${DOCKER_NETWORK} \
    --publish 3000:3000 \
    --env PORT=3000 \
    --env RABBITMQ_URL="${RABBITMQ_URL_FOR_FAKEPORTAL}" \
    --env PROXIED_RABBITMQ_URL="${RABBITMQ_URL}" \
    --env UAA_URL="${UAA_URL_FOR_FAKEPORTAL}" \
    --env CLIENT_ID="${CLIENT_ID}" \
    --env CLIENT_SECRET="${CLIENT_SECRET}" \
    -v ${FAKEPORTAL_DIR}:/code/fakeportal \
    mocha-test run fakeportal

  wait_for_url $FAKEPORTAL_URL
  end "Fakeportal is ready"
}

init_fakeproxy() {
  FAKEPROXY_URL=${FAKEPROXY_URL:-http://fakeproxy:9090}
  FAKEPROXY_DIR=${SCRIPT}/../fakeportal
  CLIENT_ID="${CLIENT_ID:-rabbit_idp_user}"
  CLIENT_SECRET="${CLIENT_SECRET:-rabbit_idp_user}"
  RABBITMQ_HOST_FOR_FAKEPROXY=${RABBITMQ_HOST_FOR_FAKEPROXY:-rabbitmq:15672}
  UAA_URL_FOR_FAKEPROXY=${UAA_URL_FOR_FAKEPROXY:-http://uaa:8080}

  RABBITMQ_URL_FOR_FAKEPROXY=$(calculate_rabbitmq_url $RABBITMQ_HOST_FOR_FAKEPROXY)

  print "> FAKEPROXY_URL: ${FAKEPROXY_URL}"
  print "> UAA_URL: ${UAA_URL_FOR_FAKEPROXY}"
  print "> RABBITMQ_HOST_FOR_FAKEPROXY: ${RABBITMQ_HOST_FOR_FAKEPROXY}"
  print "> CLIENT_ID: ${CLIENT_ID}"
  print "> CLIENT_SECRET: ${CLIENT_SECRET}"
  print "> RABBITMQ_URL_FOR_FAKEPROXY: ${RABBITMQ_URL_FOR_FAKEPROXY}"

}
start_fakeproxy() {
  begin "Starting fakeproxy ..."

  init_fakeproxy
  kill_container_if_exist fakeproxy

  docker run \
    --detach \
    --name fakeproxy \
    --net ${DOCKER_NETWORK} \
    --publish 9090:9090 \
    --env PORT=9090 \
    --env RABBITMQ_URL="${RABBITMQ_URL_FOR_FAKEPROXY}" \
    --env UAA_URL="${UAA_URL_FOR_FAKEPROXY}" \
    --env CLIENT_ID="${CLIENT_ID}" \
    --env CLIENT_SECRET="${CLIENT_SECRET}" \
    -v ${FAKEPROXY_DIR}:/code/fakeportal \
    mocha-test run fakeproxy

  wait_for_url $FAKEPROXY_URL
  end "Fakeproxy is ready"

}

wait_for_url() {
  BASE_URL=$1
  if [[ $BASE_URL == *"localhost"** ]]; then
    wait_for_url_local $BASE_URL
  else
    wait_for_url_docker $BASE_URL
  fi
}
wait_for_url_local() {
  url=$1
  max_retry=10
  counter=0
  until (curl -L -f -v $url >/dev/null 2>&1)
  do
    print "Waiting for $url to start"
    sleep 5
    [[ counter -eq $max_retry ]] && print "Failed!" && exit 1
    print "Trying again. Try #$counter"
    ((counter++))
  done
}
wait_for_url_docker() {
  url=$1
  max_retry=10
  counter=0
  until (docker run --net rabbitmq_net --rm curlimages/curl:7.85.0 -L -f -v $url >/dev/null 2>&1)
  do
    print "Waiting for $url to start"
    sleep 5
    [[ counter -eq $max_retry ]] && print "Failed!" && exit 1
    print "Trying again. Try #$counter"
    ((counter++))
  done
}

init_proxy() {
  HTTPD_CONFIG_DIR=${TEST_CONFIG_DIR}/httpd-proxy
  PUBLIC_RABBITMQ_HOST=${PUBLIC_RABBITMQ_HOST:-proxy:9090}
  PROXIED_RABBITMQ_URL=$(calculate_rabbitmq_url $PUBLIC_RABBITMQ_HOST)

  print "> HTTPD_CONFIG: ${HTTPD_CONFIG_DIR}"
  print "> PUBLIC_RABBITMQ_HOST: ${PUBLIC_RABBITMQ_HOST}"
  print "> PROXIED_RABBITMQ_URL: ${PROXIED_RABBITMQ_URL}"
  print "> RABBITMQ_HOST_FOR_PROXY: ${RABBITMQ_HOST_FOR_PROXY}"
  print "> HTTPD_DOCKER_IMAGE: ${HTTPD_DOCKER_IMAGE}"
}
start_proxy() {
  begin "Starting proxy ..."

  init_proxy
  kill_container_if_exist proxy

  MOUNT_HTTPD_CONFIG_DIR=$CONF_DIR/httpd

  mkdir -p $MOUNT_HTTPD_CONFIG_DIR
  ${BIN_DIR}/gen-httpd-conf ${HTTPD_CONFIG_DIR} $ENV_FILE $MOUNT_HTTPD_CONFIG_DIR/httpd.conf
  print "> EFFECTIVE HTTPD_CONFIG_FILE: $MOUNT_HTTPD_CONFIG_DIR/httpd.conf"

  docker run \
    --detach \
    --name proxy \
    --net ${DOCKER_NETWORK} \
    --publish 9090:9090 \
    --mount "type=bind,source=${MOUNT_HTTPD_CONFIG_DIR},target=/usr/local/apache2/conf" \
    ${HTTPD_DOCKER_IMAGE}

  wait_for_url $PROXIED_RABBITMQ_URL
  end "Proxy is ready"
}


test() {
  kill_container_if_exist mocha
  begin "Running tests with env variables:"

  RABBITMQ_HOST=${RABBITMQ_HOST:-rabbitmq:15672}
  PUBLIC_RABBITMQ_HOST=${PUBLIC_RABBITMQ_HOST:-$RABBITMQ_HOST}
  RABBITMQ_URL=$(calculate_rabbitmq_url $PUBLIC_RABBITMQ_HOST)

  print "> RABBITMQ_HOST: ${RABBITMQ_HOST}"
  print "> PUBLIC_RABBITMQ_HOST: ${PUBLIC_RABBITMQ_HOST}"
  print "> RABBITMQ_PATH: ${RABBITMQ_PATH}"
  print "> RABBITMQ_URL: ${RABBITMQ_URL}"
  print "> UAA_URL: ${UAA_URL}"
  print "> FAKEPORTAL_URL: ${FAKEPORTAL_URL}"

  docker run \
    --rm \
    --name mocha \
    --net ${DOCKER_NETWORK} \
    --env RABBITMQ_URL=${RABBITMQ_URL} \
    --env UAA_URL=${UAA_URL} \
    --env FAKE_PORTAL_URL=${FAKEPORTAL_URL} \
    --env RUN_LOCAL=false \
    -v ${TEST_DIR}:/code/test \
    -v ${SCREENS}:/screens \
    mocha-test test /code/test${TEST_CASES_PATH}

  TEST_RESULT=$?
  end "Finishing running test ($TEST_RESULT)"
  return $TEST_RESULT
}

save_logs() {
  mkdir -p $LOGS
  save_container_logs selenium
}
save_container_logs() {
  docker container ls | grep $1 >/dev/null 2>&1 && docker logs $1 > $LOGS/$1.log || echo "$1 not running"
}

profiles_with_local_or_docker() {
  if [[ "$PROFILES" != *"local"* && "$PROFILES" != *"docker"* ]]; then
    echo "$PROFILES docker"
  else
    echo "$PROFILES"
  fi
}
generate_env_file() {
    mkdir -p $CONF_DIR
    ${BIN_DIR}/gen-env-file $TEST_CONFIG_DIR $ENV_FILE
    source $ENV_FILE
}
run() {
  runWith rabbitmq
}
runWith() {
  if [[ "$COMMAND" == "run" ]]
  then
    run_on_docker_with $@
  else
    run_local_with $@
  fi
}

run_local_with() {
  export PROFILES="local ${PROFILES}"
  determine_required_components_excluding_rabbitmq $@
  init_suite
  ensure_docker_network
  generate_env_file
  build_mocha_image

  if [[ "$COMMAND" == "start-rabbitmq" ]]
  then
    start_local_rabbitmq
  elif [[ "$COMMAND" == "start-others" ]]
  then
    start_local_others
  elif [[ "$COMMAND" == "stop-others" ]]
  then
    teardown_local_others
  elif [[ "$COMMAND" =~ test[[:space:]]*([^[:space:]]*) ]]
  then
    test_local ${BASH_REMATCH[1]}
  fi
}
determine_required_components_including_rabbitmq() {
  if [[ "$@" != *"rabbitmq"* ]]; then
    REQUIRED_COMPONENTS+=("rabbitmq")
  fi
  for (( i=1; i<=$#; i++)) {
    eval val='$'$i
    REQUIRED_COMPONENTS+=( "$val" )
  }
}
determine_required_components_excluding_rabbitmq() {
  for (( i=1; i<=$#; i++)) {
    if [[ $i != "rabbitmq" ]]; then
      eval val='$'$i
      REQUIRED_COMPONENTS+=( "$val" )
    fi
  }
}
run_on_docker_with() {
  determine_required_components_including_rabbitmq $@
  export PROFILES=`profiles_with_local_or_docker`
  init_suite
  ensure_docker_network
  generate_env_file
  build_mocha_image
  start_selenium

  trap teardown_components EXIT

  start_components
  test
  TEST_RESULT=$?
  save_logs
  save_components_logs

  kill_container_if_exist selenium

  exit $TEST_RESULT
}
start_local_others() {
  if [[ $REQUIRED_COMPONENTS == "" ]]; then
    print "There are no other components"
  else
    start_components
  fi
}
teardown_local_others() {
  if [[ $REQUIRED_COMPONENTS == "" ]]; then
    print "There are no other components"
  else
    teardown_components
  fi
}
test_local() {
  begin "Running local test $1"

  RABBITMQ_HOST=${RABBITMQ_HOST:-rabbitmq:15672}
  PUBLIC_RABBITMQ_HOST=${PUBLIC_RABBITMQ_HOST:-$RABBITMQ_HOST}
  export RABBITMQ_URL=$(calculate_rabbitmq_url $PUBLIC_RABBITMQ_HOST)

  print "> RABBITMQ_HOST: ${RABBITMQ_HOST}"
  print "> PUBLIC_RABBITMQ_HOST: ${PUBLIC_RABBITMQ_HOST}"
  print "> RABBITMQ_PATH: ${RABBITMQ_PATH}"
  print "> RABBITMQ_URL: ${RABBITMQ_URL}"
  print "> UAA_URL: ${UAA_URL}"
  print "> FAKE_PORTAL_URL: ${FAKE_PORTAL_URL}"

  export RUN_LOCAL=true
  export SCREENSHOTS_DIR=${SCREENS}
  npm test $TEST_CASES_DIR/$1

}

start_components() {
  for i in "${REQUIRED_COMPONENTS[@]}"
  do
    start="start_$i"
    $start
  done
}
teardown_components() {
  begin "Tear down ..."
  for i in "${REQUIRED_COMPONENTS[@]}"
  do
    print "Tear down $i"
    $(kill_container_if_exist $i)
  done
  end "Finished teardown"
}
save_components_logs() {
  begin "Saving Logs to $LOGS ..."
  for i in "${REQUIRED_COMPONENTS[@]}"
  do
    print "Saving logs for $i"
    $(save_container_logs $i)
  done
  end "Finished saving logs"
}
