#!/bin/bash

. /home/eloyd/NWC2026-AstropotaPOD/AstropotaUtils.sh

# Default states, minimums and maximums, etc
mqtt_host="192.168.0.6"
debug=""
min=""
max=""
warn=""
crit=""
exitCode="0"
statusText="OK"

# Definitions for where the AstropotaPOD is located (using Nagios Global Headquarters)
LAT="44.973N"
LON="93.155W"
TARGET_TZ="EDT"
sunwait="/home/eloyd/NWC2026-AstropotaPOD/sunwait"

do_debug() {
  [ -z "$debug" ] && return
  echo "DEBUG: $*" >&2
}

do_help() {
  echo "Usage: $0 -w <warn> -c <crit> -m <min> -M <max> [-d] (kp | flux | sun | puck <field> | NINA <topic> | weather <field> | ppba <field>)"
  exit
}

while getopts "w:c:m:M:hd" opt; do
  case "$opt" in
    w) warn="$OPTARG";;
    c) crit="$OPTARG";;
    m) min="$OPTARG";;
    M) max="$OPTARG";;
    h) do_help;;
    d) debug="true";;
  esac
done
shift $((OPTIND - 1))
command="$@"
[ "$warn" = "-c" -o "$warn" = "ignored" ] && warn=""
[ "$crit" = "ignored" ] && crit=""
[ "$min" = "-M" -o "$min" = "ignored" ] && min=""
[ "$max" = "ignored" ] && max=""
do_debug "We'll be looking for: $command [-w $warn] [-c $crit] [-m $min] [-M $max]"

get_weather() {
  do_debug "In get_weather"
  do_debug "mosquitto_sub -W 5 -h $mqtt_host -t AstropotaPOD/weather/$1 -C 1"
  mosquitto_sub -W 5 -h $mqtt_host -t AstropotaPOD/weather/$1 -C 1
}

convert_to_time_t() {
  theTime="$1"
  whatDay="${2:-today}"
  theTZ="${3:-EDT}"
  do_debug "convert_to_time_t: theTime=$theTime, whatDay=$whatDay"
  NOW=$(date +%s)		# Now in time_t
  theDate=$(date -d "$whatDay" +"%d-%b-%Y")
  do_debug "theDate=$theDate"
  nextEvent=$(date -d "$theDate $theTime ${theTZ}" +%s)
  do_debug "nextEvent=$nextEvent"
  echo "$nextEvent"
}

# Sunwait will get today's rise (rise) today's set (set) or tomorrow's rise (tomorrow)
get_sunrise() {
  do_debug "In get_sunrise"
  NOW=$(date +%s)
do_debug "NOW=$NOW"
  dawnTime=$($sunwait list 1 nautical rise $LAT $LON | tail -1)
  nextDawn=$(convert_to_time_t $dawnTime)
  # If it's 2am, then NOW is less than DAWN, we don't need to do anything.
  # If it's 2pm, then NOW is greater than DAWN, so we need to get tomorrow's dawn.
  if [ "$NOW" -gt "$nextDawn" ]; then
    do_debug "Need to look at tomorrow's dawn"
    dawnTime=$($sunwait list 2 nautical rise $LAT $LON | tail -1)
    nextDawn=$(convert_to_time_t $dawnTime tomorrow)
    do_debug "Tomorrow's dawn is nextDawn=$nextDawn"
  else
    do_debug "Dawn is still in the future for today, so the next dawn is today's dawn: $nextDawn"
  fi
do_debug "dawnTime=$dawnTime, nextDawn=$nextDawn"
  duskTime=$($sunwait list nautical set $LAT $LON)
  nextDusk=$(date -d "${dateToday} ${duskTime} ${TARGET_TZ}" +%s)
do_debug "duskTime=$duskTime, nextDusk=$nextDusk"
  echo "nextDusk=$nextDusk, nextDawn=$nextDawn"
}

get_mqtt() {
  do_debug "In get_mqtt"
  do_debug "mosquitto_sub -W 5 -h $mqtt_host -t \"$1\" -C 1"
  mosquitto_sub -W 5 -h $mqtt_host -t "$1" -C 1
}

get_puck() {
  do_debug "In get_puck"
  do_debug "mosquitto_sub -W 5 -h $mqtt_host -t AstropotaPOD/sensor/AstropotaPOD-e9af/$1 -C 1"
  mosquitto_sub -W 5 -h $mqtt_host -t AstropotaPOD/sensor/AstropotaPOD-e9af/$1 -C 1
}

get_ppba() {
  do_debug "In get_ppba"
  do_debug "mosquitto_sub -W 5 -h $mqtt_host -t PPBA/status/$1 -C 1"
  mosquitto_sub -W 5 -h $mqtt_host -t PPBA/status/$1 -C 1
}

get_NINA() {
  do_debug "In get_NINA"
  do_debug "mosquitto_sub -W 5 -h $mqtt_host -t Astro/NINA/$1 -C 1"
  mosquitto_sub -W 5 -h $mqtt_host -t Astro/NINA/$1 -C 1
}

get_suntime() {
  do_debug "In get_suntime"
  ${sunwait} poll nautical $LAT $LON >/dev/null
  sunState=$?
  do_debug "sunState=$sunState"
  exitCode=0
  statusText="OK"
  case "$sunState" in
    2) exitCode=1; statusText="WARNING - Sky is too bright for imaging.";;
    3) exitCode=0; statusText="OK - Sky is dark. Safe to image deep-sky targets.";;
    *) exitCode=3; statusText="UNKNOWN - invalid code returned from sunwait command";;
  esac
  sunRise=$(get_sunrise)
  echo "${statusText} | IsDark=$exitCode, $sunRise;;;;"
  exit $exitCode
}

# main
value=""
do_debug "command is $command"
case "$command" in
  f*|F*) command="10MeV-Flux"; value=$(curl -s "https://services.swpc.noaa.gov/json/goes/primary/integral-protons-7-day.json" | jq '. | map(select(.energy == ">=10 MeV")) | last | .flux');;
  k*|K*) command="Kp-Index"; value=$(curl -s https://services.swpc.noaa.gov/products/noaa-planetary-k-index.json | jq '[last][].Kp');;
  n*|N*) command="$2"; value=$(get_NINA $2);;
  s*|S*) command="Suntime"; get_suntime;;
  t*|T*) command="SunRiseSunSet"; value=$(get_sunrise);;
  w*|W*) command="$2"; value=$(get_weather $2);;
  mqtt*) command="$2"; value=$(get_mqtt $2);;
  ppba*) command="$2"; value=$(get_ppba $2);;
  puck*) command="$2"; value=$(get_puck $2);;
  *) echo "unknown command was $command";;
esac

# --- FLOATING POINT FORMATTING ---
# If value is not empty/unknown, check its formatting
if [ "$value" != "?" ]; then
    # 1. First, check if it contains RA/Dec formatting symbols (: or °)
    # If it does, bypass formatting completely to preserve the raw coordinate string
    if [[ "$value" == *":"* ]] || [[ "$value" == *"°"* ]]; then
        value="$value"

    # 2. Otherwise, check if it's a strict decimal number and pad/round to 4 spaces
    elif [[ "$value" =~ ^-?[0-9]+\.[0-9]+$ ]]; then
        value=$(printf "%.4f" "$value")
    fi
fi
# CRITICAL check must always run first to ensure it takes precedence
statusText=$(check_threshold "$value" "$warn" "$crit")
exitCode=$?
echo "$command $statusText: $value|$command=$value;$warn;$crit;$min;$max"
exit $exitCode

# --- NAGIOS OUTPUT STAGE ---
# Because check_threshold already figured out the severity, we just match the exit code
case $EXIT_CODE in
    0)
        echo "OK - Value is $value | $command=$value;$warn;$crit;$min;$max"
        exit 0
        ;;
    1)
        echo "WARNING - Value $value is outside of warning range ($warn) | $command=$value;$warn;$crit;$min;$max"
        exit 1
        ;;
    2)
        echo "CRITICAL - Value $value is outside of critical range ($crit) | $command=$value;$warn;$crit;$min;$max"
        exit 2
        ;;
    *)
        echo "UNKNOWN - Received unexpected response from check engine | $command=$value;$warn;$crit;$min;$max"
        exit 3
        ;;
esac

