#!/usr/bin/env bash

set -o pipefail

declare FMT_RESET
declare FMT_BOLD
declare FMT_GREEN
declare FMT_RED
declare NL
FMT_RESET=$(printf "\\e[0m")
FMT_BOLD=$(printf "\\e[1m")
FMT_GREEN=$(printf "\\e[32m")
FMT_RED=$(printf "\\e[31m")
NL=$'\n'
readonly FMT_RESET
readonly FMT_BOLD
readonly FMT_GREEN
readonly FMT_RED
readonly NL


function usage() {
    cat << __EOF__
${FMT_GREEN}$(basename "$0")${FMT_RESET}: \

Ping hosts and print status

${FMT_BOLD}Usage:${FMT_RESET}
    $(basename "$0") [-h] [--service|--network]

${FMT_GREEN}-h --help${FMT_RESET}
    Print this message and exit.

${FMT_GREEN}--services${FMT_RESET}
    Report service status

${FMT_GREEN}--network${FMT_RESET}
    Report network status

__EOF__
}

function _fmt_online() { echo "${FMT_BOLD}${FMT_GREEN}ONLINE${FMT_RESET}"; }

function _fmt_offline() { echo "${FMT_BOLD}${FMT_RED}OFFLINE${FMT_RESET}"; }

function _test_cmd() { if eval "$1" &>/dev/null ; then echo "${2}~$(_fmt_online)"; else echo "${2}~$(_fmt_offline)"; fi }

function _test_ping() { _test_cmd "ping -W 2 -c 1 ${1}" "${2}"; }

function _test_curl_head() { _test_cmd "curl --fail --head ${1}" "${2}"; }

function _test_curl_get() { _test_cmd "curl --fail --get ${1}" "${2}"; }

function _test_curl_insecure() { _test_cmd "curl --fail --head --insecure ${1}" "${2}"; }

function _test_netcat() { _test_cmd "nc -z ${1} ${2}" "${3}"; }

function network() {
  local uplink_address="1.1.1.1"

  declare -a infra=("core.en1.local" "switch.en1.local" "wap-1.en1.local" "wap-2.en1.local" "wap-3.en1.local" "printer.en1.local")
  declare -a infra_names=("Core Router" "Core Switch" "Wireless AP 1" "Wireless AP 2" "Wireless AP 3" "Printer")

  declare -a lab=("cluster.skylab.enp.one" "pegasus.skylab.enp.one" "saturn.skylab.enp.one" "orion.skylab.enp.one" "iridium.skylab.enp.one" "en2.enp.one")
  declare -a lab_names=("Cluster" "Pegasus" "Saturn" "Orion" "Iridium" "Hubble")

  local output=$(_test_ping "$uplink_address" "UPLINK")
  output+="${NL}";

  output+="${NL}INFRASTRUCTURE~STATE${NL}"
  for (( index=0; index<"${#infra[@]}"; index++ )); do
    output+=$(_test_ping "${infra[$index]}" "${infra_names[$index]}")
    output+="${NL}"
  done

  output+="${NL}HOMELAB~STATE${NL}"
  for (( index=0; index<"${#lab[@]}"; index++ )); do
    output+=$(_test_ping "${lab[$index]}" "${lab_names[$index]}")
    output+="${NL}"
  done

  column -e -t -s '~' <<<"$output"
}

function services() {
  local output="INTERNAL~STATE${NL}"

  output+=$(_test_netcat "cluster.skylab.enp.one" "53" "AdGuard DNS")
  output+="${NL}"
  output+=$(_test_netcat "core.en1.local" "53" "Fallback DNS")
  output+="${NL}"
  output+=$(_test_curl_insecure "https://cluster.skylab.enp.one:8443/status" "Ubiquiti WLC")
  output+="${NL}"

  output+="${NL}PUBLIC~STATE${NL}"

  output+=$(_test_curl_head "https://pms.enp.one/web/index.html" "Plex Media Server")
  output+="${NL}"
  output+=$(_test_netcat "cluster.skylab.enp.one" "25565" "Minecraft Server")
  output+="${NL}"
  output+=$(_test_curl_get "https://vcs.enp.one/api/v1/version" "Version Control")
  output+="${NL}"
  output+=$(_test_curl_get "https://ssv.enp.one/api/alive" "Bitwarden")
  output+="${NL}"
  output+=$(_test_curl_head "https://cdn.enp.one/heartbeat" "Digital Ocean CDN")
  output+="${NL}"
  output+=$(_test_curl_head "https://doc.enp.one/" "Documentation")
  output+="${NL}"
  output+=$(_test_curl_head "https://enpaul.net/" "enpaul.net")
  output+="${NL}"
  output+=$(_test_curl_head "https://allaroundhere.org/" "allaroundhere.org")
  output+="${NL}"
  output+=$(_test_curl_head "https://enp.one/" "enp.one")
  output+="${NL}"

  column -e -t -s'~' <<<"$output"
}

function main() {
  if [[ "$1" =~ ^(-h|--help)$ ]]; then
    usage;
    return 0
  fi
  if [[ "$1" = "--network" ]]; then
    network;
    return 0
  fi
  if [[ "$1" = "--services" ]]; then
    services;
    return 0
  fi
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  main "${@}"
fi
