#!/bin/bash

# Enter your zipcode here for local weather.
zipcode=20001
# Add the services you want to monitor here as an array
#  e.g. ('apache2' 'gitea' 'postfix')
servicelist=('apache2' 'gitea' 'postfix')

# Disks to check (pls only do one for now)
disks=('/dev/sda1')
# Colors are nice
blk=$(tput setaf 0)
red=$(tput setaf 1)
grn=$(tput setaf 2)
ylw=$(tput setaf 3)
blu=$(tput setaf 4)
cyn=$(tput setaf 6)
wht=$(tput setaf 7)
und=$(tput smul)
bld=$(tput bold)
# Uncoloring is important
rst=$(tput sgr0)
# Get the number of columns and rows to center the
#  last updated time on the bottom of the window.
cols=$(tput cols)
rows=$(tput lines)

# trap ctrl-c and call ctrl_c()
# https://rimuhosting.com/knowledgebase/linux/misc/trapping-ctrl-c-in-bash
trap ctrl_c INT

function ctrl_c() {
 #clear
 tput cnorm
 echo "${rst}${red}CTRL+C Detected, exiting.${rst}"
 exit
}

function dothething() {
 # Grab the size of the window again as the window size
 #  may have changed since the script was started.
 cols=$(tput cols)
 rows=$(tput lines)
 clear
 updatedstring="Last updated: `date \"+%F %X\"`"
 # Sometimes this may not complete due to wttr.in running
 #  out of available queries to their weather provider.
 #  This should only last for a day or so.
 curl wttr.in/${zipcode}?1QnuFA
 # Make sure the updated line is at the bottom of the screen
 down=$rows
 # Do some math to center the string horizontally
 let over="$cols/2-${#updatedstring}/2"
 # Move the cursor over to the correct starting location
 tput cup $down $over
 # Print the last time the weather was updated
 echo -n "${rst}${ylw}${updatedstring}${rst}"
 # Reset the cursor back to 0,0
 tput cup 0 0
}

# Check to see if we need to reboot the server
function rebootcheck() {
 cols=$(tput cols)
 reboottext_notneeded="  No reboot required"
 reboottext_needed="A reboot is required"
 if [ -f /var/run/reboot-required ]; then
  # Reboot required
  let over="$cols-${#reboottext_needed}"
  tput cup 0 $over
  echo -en "${rst}${bld}${red}${reboottext_needed}${rst}"
 else
  # No reboot needed
  let over="$cols-${#reboottext_notneeded}-1"
  tput cup 0 $over
  echo -en "${rst}${grn}${reboottext_notneeded}${rst}"
 fi
}

# Disk space check
function checkdisks() {
 _df=`df -h | tr -s [:blank:] | egrep "^${disks[0]} "`

 disk=`echo $_df | cut -d' ' -f1` # /dev/sda1
 size=`echo $_df | cut -d' ' -f2` # 20G
 used=`echo $_df | cut -d' ' -f3` # 16G
 left=`echo $_df | cut -d' ' -f4` # 6.1G
 perc=`echo $_df | cut -d' ' -f5` # 69%
 mntp=`echo $_df | cut -d' ' -f6` # /
 rper=`echo $perc | tr -d "%"`    # 69

 capvalues=(85 90 95)
 capcolors=("${ylw}" "${bld}${red}" "${red}")

 capcolor=""
 if [ $rper -lt ${capvalues[0]} ]; then
  capcolor="${wht}"
 elif [ $rper -ge ${capvalues[0]} ] && [ $rper -lt ${capvalues[1]} ]; then
  capcolor="${capcolors[0]}"
 elif [ $rper -ge ${capvalues[1]} ] && [ $rper -lt ${capvalues[2]} ]; then
  capcolor="${capcolors[1]}"
 elif [ $rper -ge ${capvalues[2]} ]; then
  capcolor="${capcolors[2]}"
 fi

 title="Disk usage"
 usage="${used}/${size}"

 cols=$(tput cols)
 let overt="$cols-${#title}-1"
 let overd="$cols-${#disk}-1"
 let overu="$cols-${#usage}-1"

 tput cup 2 $overt
 echo -en "${rst}${title}${rst}"
 tput cup 3 $overd
 echo -en "${rst}${disk}${rst}"
 tput cup 4 $overu
 echo -en "${rst}${capcolor}${usage}${rst}"
}


# This be where we check the services
function servicecheck(){
 # If we're not monitoring any services, return
 [ ${#servicelist[@]} -eq 0 ] && return
 # These are the allowed rows
 # TODO? determine lines from after weather print?
 servicerow=(15 16 17 18 19)
 # These are the allowed columns
 # TODO? allow column count instead of static assignments?
 servicecol=(1 25 50)
 # Loop over the number of services that we're monitoring
 # https://askubuntu.com/a/1340735
 for index in $(seq 0 $((${#servicelist[@]}-1))); do
  # Determine the position of the current service
  #  we go across and then down
  # TODO? allow for variable columns?
  let echocol="${servicecol[${index}%3]}"
  let echorow="${servicerow[${index}/3]}"
  # Put our cursor where we can print
  tput cup $echorow $echocol
  # Clear the variables we use
  #unset echocol echorow
  # Do the actual service check. is-active returns
  #  active or inactive. Easy peasy
  servicestatus=`systemctl is-active ${servicelist[${index}]}`
  # Print out the status, green with a dot (\U25CF) if it's online,
  #  a red with a square (\U25A0) if it's stopped, or a yellow
  #  triangle (\U25BA) if it's starting.
  case "${servicestatus}" in
   active) echo -en "${grn}\U25CF ${servicelist[${index}]}${rst}";;
   activating) echo -en "${ylw}\U25BA ${servicelist[${index}]}${rst}";;
   inactive) echo -en "${red}\U25A0 ${servicelist[${index}]}${rst}";;
   failed) echo -en "${red}\U25A0 ${servicelist[${index}]}${rst}";;
  esac

#[ "${servicestatus}" == "active" ] && echo -en "${grn}\U25CF ${servicelist[${index}]}${rst}" || [ "${servicestatus}" == "activating" ] && echo -en "${ylw}\U25BA ${servicelist[${index}]}${rst}" || echo -en "${red}\U25A0 ${servicelist[${index}]}${rst}"

 done
 tput cup 0 0
}


# Clear the screen and let's get going
clear
# Make the cursor invisible for the terminal
tput civis
# Programmers are great at naming things
dothething
# Check if a reboot is needed
rebootcheck
# Check the disk capacities
checkdisks
# Loop forever. Use ctrl+c to exit.
while true; do
 # We want to make sure we only check once per hour
 #  in order to not overwhelm the wttr.in service.

 # Octal fix: https://stackoverflow.com/a/24777667
 if [ `date +%M` -eq "00" ]; then
  # Don't forget to check the seconds or it'll run
  #  the command every second of the 0th minute.
  if [ `date +%S` -eq "00" ]; then
   dothething
   # Also doing these once per hour because more seems overkill
   rebootcheck
   checkdisks
  fi
 fi
 # I don't think checking every second is a problem... yet...
 servicecheck
 # Sleep for a second so we're not hammering the system
 #  with date checks.
 sleep 1
done