#!/bin/ash
# shellcheck shell=dash

set -e

CONTAINER="$CONTAINER_NAME"
HOST_PORT="localhost"                  # Default value to ping localhost
HOST_PING="www.google.com"
MOUNT_OK=0
PORT_OK=0
PING_OK=0
ADDITIONAL_OK=0
LOG_FILE="/4me/logs/healthcheck.log"
[ -f "$LOG_FILE" ] || LOG_FILE="/opt/logs/healthcheck.log"
DEBUG=false

# Configuration: container_name:port_number:healthcheck_key:needs_mount:additional_check
CONTAINERS="
bazarr:6767:MqxKFtWn8b:1:
dns-floor0:5380:DEMcDbV3jm:0:
flaresolverr:8191:1D269uUSPN:0:
nzbget:6789:1rhVmN3CvU:0:
pg:5432:KcMaVo4DZO:0:
pia:80:6u8jl0wW8x:0:
prowlarr:9696:6zHrWoMiE3:0:
qbt:8080:8bTFshVlQW:0:
radarr:7878:sbN4Qa3oEJ:1:
scrutiny-ket:8080:11NiNUlyD3:0:
scrutiny-ket-db:8086:kxjq9qUuDh:0:
scrutiny-ket-web:8080:vO2TaP5u8S:0:
sonarr:8989:BGPj1HwmjJ:1:
"



# ------------- Functions -----------------

# Function to parse arguments
parse_args() {
  while [[ $# -gt 0 ]]; do
    case "$1" in
      -d|--debug)
        DEBUG=true
        shift
        ;;
      -p|--host_ping)
        HOST_PING="$2"
        shift 2
        ;;
      -c|--container)
        CONTAINER_NAME="$2"
        CONTAINER="$CONTAINER_NAME"
        shift 2
        ;;
      -q|--host_portcheck)
        HOST_PORT="$2"
        shift 2
        ;;
      -a|--additional)
        ADDITIONAL_CHECK="$2"
        shift 2
        ;;
      -h|--help)
        echo "Usage: $0 [-d|--debug] [-c|--container CONTAINER_NAME] [-p|--host_ping HOST_TO_PING] [-q|--host_portcheck HOST_TO_CHECK_PORT] [-a|--additional ADDITIONAL_CHECK]"
        exit 0
        ;;
      *)
        echo "Unknown option: $1"
        exit 1
        ;;
    esac
  done
}

# Debug function
debug() {
  if [ "$DEBUG" = true ] || [ "$DEBUG" = "1" ]; then
    echo "[DEBUG] $*"
  fi
  return 0        # ← guarantee a zero exit status
}

check_mount() {
  [ "$NEEDS_MOUNT" = "0" ] && return 
  MOUNT_POINT="${1:-/media/backup}"
  debug "Checking mount for $MOUNT_POINT"

  if mount | awk '{print $3}' | grep -q -w "$MOUNT_POINT"; then
    debug "Mount check ok for $MOUNT_POINT"
    MOUNT_OK=0
  else
    debug "Mount check failed for $MOUNT_POINT"
    MOUNT_OK=1
  fi
}

check_ping() {
  debug "Checking ping to $HOST_PING"

  if command -v curl >/dev/null 2>&1; then
    curl -s --head --fail "$HOST_PING" >/dev/null 2>&1
    PING_OK=$?
  elif command -v ping >/dev/null 2>&1; then
    ping -c 1 "$HOST_PING" >/dev/null 2>&1
    PING_OK=$?
  elif command -v wget >/dev/null 2>&1; then
    wget --spider "$HOST_PING" >/dev/null 2>&1
    PING_OK=$?
  else
    echo > /dev/tcp/"$HOST_PING"/80 2>/dev/null
    PING_OK=$?
  fi

  if [ "$PING_OK" -eq 0 ]; then
    debug "Ping OK to $HOST_PING"
  else
    debug "Ping failed to $HOST_PING"
  fi
}

check_port() {
  debug "Checking port $PORT_NUMBER on $HOST_PORT"

  if [ "$PORT_NUMBER" -ne 0 ]; then
    if command -v nc >/dev/null 2>&1; then
      nc -z "$HOST_PORT" "$PORT_NUMBER" >/dev/null 2>&1
      PORT_OK=$?
    elif command -v curl >/dev/null 2>&1; then
      curl -s --fail "http://$HOST_PORT:$PORT_NUMBER" >/dev/null 2>&1
      PORT_OK=$?
    elif command -v wget >/dev/null 2>&1; then
      wget --spider "http://$HOST_PORT:$PORT_NUMBER" >/dev/null 2>&1
      PORT_OK=$?
    else
      echo > /dev/tcp/"$HOST_PORT"/"$PORT_NUMBER" 2>/dev/null
      PORT_OK=$?
    fi

    if [ "$PORT_OK" -eq 0 ]; then
      debug "Port $PORT_NUMBER is open"
    else
      debug "Port $PORT_NUMBER is closed"
    fi
  else
    debug "No port to check"
    PORT_OK=0
  fi
}

check_additional() {
  debug "Running additional check: $ADDITIONAL_CHECK"
  if [ -z "$ADDITIONAL_CHECK" ]; then
    ADDITIONAL_OK=0
  else
    debug "Executing: $ADDITIONAL_CHECK"
    set +e
    eval "$ADDITIONAL_CHECK"
    ADDITIONAL_OK=$?
    set -e
  fi
}

send_result() {
  set +e
  HC_URL="https://uptime.noxs.me/api/push/$HEALTHCHECK_KEY?status=$HC_STATUS&msg=OK&ping="
  if command -v curl >/dev/null 2>&1; then
    curl -m 10 --retry 5 "$HC_URL" -o /dev/null 2>&1
  elif command -v wget >/dev/null 2>&1; then
    wget --spider --tries=5 --no-verbose --no-check-certificate "$HC_URL"
  else
    debug "Using openssl to send healthcheck result"
    HOST="uptime.noxs.me"
    PORT=443
    debug "Sending healthcheck GET /api/push/${HEALTHCHECK_KEY}?status=${HC_STATUS}&msg=OK&ping= HTTP/1.1\r\nHost: ${HOST}\r\nConnection: close\r\n\r\n"
    REQUEST="GET /api/push/${HEALTHCHECK_KEY}?status=${HC_STATUS}&msg=OK&ping= HTTP/1.1\r\nHost: ${HOST}\r\nConnection: close\r\n\r\n"
    # Send request
    printf "${REQUEST}" | openssl s_client -quiet -connect "${HOST}:${PORT}" 2>/dev/null
  fi
  set -e
}

# ------------- Main logic -----------------

# Get param provided by the script call
parse_args "$@"

# Find container settings
for entry in $CONTAINERS; do
    container_name=$(echo "$entry" | cut -d':' -f1)
    port_number=$(echo "$entry" | cut -d':' -f2)
    healthcheck_key=$(echo "$entry" | cut -d':' -f3)
    needs_mount=$(echo "$entry" | cut -d':' -f4)
    if [ "$CONTAINER" = "$container_name" ]; then
        PORT_NUMBER="$port_number"
        HEALTHCHECK_KEY="$healthcheck_key"
        NEEDS_MOUNT="$needs_mount"
        break
    fi
done

# If container not found
if [ -z "$HEALTHCHECK_KEY" ]; then
    debug "Unknown container: $CONTAINER" >&2
    exit 1
fi

# Run the checks
check_mount
check_ping
check_port
check_additional

debug "PORT_NUMBER: $PORT_NUMBER _
      HEALTHCHECK_KEY: $HEALTHCHECK_KEY _
      NEEDS_MOUNT: $NEEDS_MOUNT _
      MOUNT_OK: $MOUNT_OK _
      PING_OK: $PING_OK _
      PORT_OK: $PORT_OK _
      ADDITIONAL_OK: $ADDITIONAL_OK"

# Determine healthcheck result
if [ "$MOUNT_OK" -eq 0 ] && [ "$PING_OK" -eq 0 ] && [ "$PORT_OK" -eq 0 ] && [ "$ADDITIONAL_OK" -eq 0 ]; then
    debug "All checks passed"
    RET=0
    HC_STATUS="up"
else
    debug "One or more checks failed"
    RET=1
    HC_STATUS="down"
fi

# Send result
send_result

exit "$RET"