#!/usr/bin/env sh
set -e

DOCKER_SOCK=${DOCKER_SOCK:-/var/run/docker.sock}
TMP_DIR=/tmp/restart
CURL_TIMEOUT=${CURL_TIMEOUT:-30}

# SIGTERM-handler
term_handler() {
  exit 143; # 128 + 15 -- SIGTERM
}

docker_curl() {
  curl --max-time "${CURL_TIMEOUT}" --no-buffer -s --unix-socket "${DOCKER_SOCK}" "$@"
}

trap 'kill ${!}; term_handler' SIGTERM

if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then
  
  mkdir -p $TMP_DIR

  # https://docs.docker.com/engine/api/v1.25/

  # Set container selector
  if [ "$AUTOHEAL_CONTAINER_LABEL" == "all" ]; then
    selector() {
      jq -r .[].Id
    }
  else
    selector() {
      jq -r '.[] | select(.Labels["'${AUTOHEAL_CONTAINER_LABEL:=autoheal}'"] == "true") | .Id'
    }
  fi

  echo "Monitoring containers for unhealthy status"
  while true; do
    sleep ${AUTOHEAL_INTERVAL:=5}

    CONTAINERS=$(docker_curl -XGET http://localhost/containers/json | selector)
    for CONTAINER in $CONTAINERS; do
      HEALTH=$(docker_curl -XGET http://localhost/containers/${CONTAINER}/json | jq -r .State.Health.Status)
      if [ "unhealthy" = "$HEALTH" ]; then
        DATE=$(date +%d-%m-%Y" "%H:%M:%S)
        CONTAINER_NAME=$(docker_curl -XGET http://localhost/containers/${CONTAINER}/json | jq -r .Name)
        echo "$DATE Container ${CONTAINER_NAME} (${CONTAINER:0:12}) found to be unhealthy"
        touch "$TMP_DIR/$CONTAINER"
      fi
    done
    for CONTAINER in `ls $TMP_DIR`; do 
        DATE=$(date +%d-%m-%Y" "%H:%M:%S)
        CONTAINER_NAME=$(docker_curl -XGET http://localhost/containers/${CONTAINER}/json | jq -r .Name)
        if [ "null" = "$CONTAINER_NAME" ]; then
          echo "$DATE Delete container ${CONTAINER_NAME} (${CONTAINER:0:12}) from restart list because container name null implies container does not exist"
          rm "$TMP_DIR/$CONTAINER"
        else
          echo "$DATE Restarting container ${CONTAINER_NAME} (${CONTAINER:0:12})"
          docker_curl -f -XPOST http://localhost/containers/${CONTAINER}/restart && rm "$TMP_DIR/$CONTAINER" || echo "$DATE Restarting container ${CONTAINER:0:12} failed"
        fi
    done
  done

else
  exec "$@"
fi
