#!/usr/bin/env bash
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"

check_all_processes() {
  local APP="$1"
  CHECK_PROC_TYPE="$2"
  local VALID_CHECK_PROC_TYPE=false

  local line
  local PROC_TYPE
  local PROC_COUNT
  while read -r line || [[ -n "$line" ]]; do
    local PROC_TYPE=${line%%=*}
    local PROC_COUNT=${line#*=}

    if [[ -n "$CHECK_PROC_TYPE" ]] && [[ "$CHECK_PROC_TYPE" != "$PROC_TYPE" ]]; then
      continue
    fi

    VALID_CHECK_PROC_TYPE=true
    if [[ "$(is_app_proctype_checks_disabled "$APP" "$PROC_TYPE")" == "true" ]]; then
      dokku_log_info1 "Zero downtime is disabled for app ($APP.$PROC_TYPE). Skipping checks"
      continue
    fi

    check_process_type "$APP" "$PROC_TYPE" "$PROC_COUNT"
  done < <(plugn trigger ps-current-scale "$APP")

  if [[ "$VALID_CHECK_PROC_TYPE" == "false" ]]; then
    dokku_log_fail "Invalid process type specified ($APP.$CHECK_PROC_TYPE)"
  fi
}

check_process_type() {
  local APP="$1" PROC_TYPE="$2" PROC_COUNT="$3"
  local CONTAINER_INDEX=1

  while [[ $CONTAINER_INDEX -le $PROC_COUNT ]]; do
    check_process "$APP" "$PROC_TYPE" "$CONTAINER_INDEX"
    local CONTAINER_INDEX=$((CONTAINER_INDEX + 1))
  done
}

check_process() {
  local APP="$1" PROC_TYPE="$2" CONTAINER_INDEX="$3"
  local CONTAINER_ID DOKKU_CONTAINER_ID_FILE IMAGE IP IS_HEROKUISH_CONTAINER PORT
  DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_TYPE.$CONTAINER_INDEX"

  if [[ ! -f "$DOKKU_CONTAINER_ID_FILE" ]]; then
    dokku_log_fail "Invalid container index specified ($APP.$PROC_TYPE.$CONTAINER_INDEX)"
  fi

  IS_HEROKUISH_CONTAINER=false
  IMAGE=$(get_app_image_name "$APP")
  is_image_herokuish_based "$IMAGE" "$APP" && IS_HEROKUISH_CONTAINER=true

  dokku_log_info1 "Running checks for app ($APP.$PROC_TYPE.$CONTAINER_INDEX)"
  CONTAINER_ID=$(<"$DOKKU_CONTAINER_ID_FILE")
  IP="$(plugn trigger network-get-ipaddr "$APP" "$PROC_TYPE" "$CONTAINER_ID")"
  PORT=5000

  while read -r port_map; do
    proxy_scheme="$(awk -F ':' '{ print $1 }' <<<"$port_map")"
    proxy_host_port="$(awk -F ':' '{ print $2 }' <<<"$port_map")"
    proxy_container_port="$(awk -F ':' '{ print $3 }' <<<"$port_map")"
    if [[ "$proxy_scheme" != "udp" ]]; then
      PORT="${proxy_container_port:="$proxy_container_port"}"
    fi
  done < <(plugn trigger ports-get "$APP")

  plugn trigger check-deploy "$APP" "$CONTAINER_ID" "$PROC_TYPE" "$PORT" "$IP"
}

cmd-checks-run() {
  declare desc="run zero-downtime checks for app/proctypes"
  declare cmd="checks:run"
  [[ "$1" == "$cmd" ]] && shift 1
  declare APP="$1"

  verify_app_name "$APP"
  local PROCTYPES="${2:-_all_}"

  dokku_log_info1 "Running pre-flight checks"
  if [[ "$PROCTYPES" == "_all_" ]]; then
    check_all_processes "$APP"
  else
    local PROC_TYPE OIFS="$IFS" IFS=,
    for PROC_TYPE in $PROCTYPES; do
      IFS="$OIFS"

      local CONTAINER_INDEX=$(echo "$PROC_TYPE" | cut -d'.' -f2 -s)
      local PROC_TYPE=$(echo "$PROC_TYPE" | cut -d'.' -f1)
      if [[ -n "$CONTAINER_INDEX" ]]; then
        check_process "$APP" "$PROC_TYPE" "$CONTAINER_INDEX"
      else
        check_all_processes "$APP" "$PROC_TYPE"
      fi
    done
  fi
}

cmd-checks-run "$@"
