#!/bin/bash -
#===============================================================================
#
#         FILE: check_week
#
#        USAGE: ./check_week -h -i -v [week_number]
#
#  DESCRIPTION: Checks the upcoming week, or any week, to ensure there are shows
#               on the IA for that period. It mainly makes sense to look into
#               the future, but you can look backwards in the same year if
#               required.
#
#      OPTIONS: ---
# REQUIREMENTS: ---
#         BUGS: ---
#        NOTES: ---
#       AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
#      VERSION: 0.0.2
#      CREATED: 2022-01-27 10:45:41
#     REVISION: 2022-02-25 22:22:19
#
#===============================================================================

set -o nounset                              # Treat unset variables as an error

SCRIPT=${0##*/}
# DIR=${0%/*}
VERSION="0.0.2"

STDOUT="/dev/fd/2"

#
# Select the appropriate working directory
#
case $(hostname) in
    i7-desktop)
        BASEDIR="$HOME/HPR/InternetArchive"
        ;;
    hprvps|marvin|borg)
        BASEDIR="$HOME/IA"
        ;;
    *)
        echo "Wrong host!"
        exit 1
        ;;
esac

cd "$BASEDIR" || exit 1

#
# Load library functions
#
LIB="$HOME/bin/function_lib.sh"
[ -e "$LIB" ] || { echo "Unable to source functions"; exit 1; }
# shellcheck source=/home/cendjm/bin/function_lib.sh
source "$LIB"

#
# Colour codes
#
define_colours

#===  FUNCTION  ================================================================
#         NAME: _open_tunnel
#  DESCRIPTION: Opens the SSH tunnel to the HPR server if necessary
#   PARAMETERS: 
#      RETURNS: 
#===============================================================================
_open_tunnel () {
    local open_tunnel="${1}"

    if [[ $(pgrep -u "$USER" -f 'ssh.*hpr@hackerpublicradio.org' -c) -eq 0 ]]; then
        $open_tunnel || { echo "Failed to open SSH tunnel"; exit 1; }
    fi
}

#===  FUNCTION  ================================================================
#         NAME: _DEBUG
#  DESCRIPTION: Writes a message if in DEBUG mode
#   PARAMETERS: List of messages
#      RETURNS: Nothing
#===============================================================================
_DEBUG () {
    [ "$DEBUG" == 0 ] && return
    for msg in "$@"; do
        printf 'D> %s\n' "$msg"
    done
}

#===  FUNCTION  ================================================================
#         NAME: _usage
#  DESCRIPTION: Reports usage; always exits the script after doing so
#   PARAMETERS: 1 - the integer to pass to the 'exit' command
#      RETURNS: Nothing
#===============================================================================
_usage () {
    local -i result=${1:-0}

    cat >$STDOUT <<-endusage
${SCRIPT} - version: ${VERSION}

Usage: ./${SCRIPT} [-h] [week_no]

Checks a future week to ensure all the shows are on the Internet Archive.

Options:
    -h                  Print this help
    -v                  Enable verbose mode where a little more information is
                        output. Mainly the dates relating to the chosen week
                        number.
    -i                  Ignore shows missing from the database during the
                        chosen week. Normally the script does not proceed if
                        there are fewer than 5 shows in a week.

Arguments:
    week_no             (optional, default current week) the week number to be
                        examined. This is a number in the range 1..52.
                        Anything else is illegal.

Environment variables
    check_week_DEBUG    If set to a non-zero value then the debugging
                        statements in the script are executed. Otherwise if
                        set to zero, or if the variable is absent no debug
                        information is produced.  The variable can be set
                        using the 'export' command or on the same line as the
                        command calling the script.  See the example below.

Examples
    ./check_week        # Check the current week
    ./check_week -i     # Check the current week ignoring missing shows
    ./check_week 6      # Check week 6 of the current year

    check_week_DEBUG=1 ./check_week     # Run with debugging enabled

endusage
    exit "$result"
}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#
# Debug mode. Invoke it with: 'check_week_DEBUG=1 ./check_week'
#
DEBUGVAR="${SCRIPT}_DEBUG"
DEBUG="${!DEBUGVAR:-0}"

#
# Process options
#
while getopts hiv opt
do
    case "${opt}" in
        h) _usage 1;;
        i) IGNORE=1;;
        v) VERBOSE=1;;
        *) _usage 1;;
    esac
done
shift $((OPTIND - 1))

IGNORE=${IGNORE:-0}
VERBOSE=${VERBOSE:-0}

#
# Check arguments
#
if [[ $# -gt 1 ]]; then
    _usage 1
    exit 1
fi

#
# Default missing any week number and validate what's found. Take care that
# numbers with leading zeroes are by default taken to be octal! We coerce to
# base 10 just in case.
#
weekno="${1:-"$(date +%V)"}"
weekno=$((10#$weekno))
if [[ ! $weekno =~ ^[0-9]{1,2}$ ]]; then
    echo "Invalid week number: $weekno"
    exit 1
fi
if [[ $weekno -lt 1 || $weekno -gt 52 ]]; then
    echo "Invalid week number: $weekno"
    exit 1
fi

#
# Check dependencies
#
OTUNNEL=$(command -v open_tunnel)
if [[ -z $OTUNNEL ]]; then
    echo "Can't find the script 'open_tunnel'"
    exit 1
fi

QUERYTOOL=$(command -v query2csv)
if [[ -z $QUERYTOOL ]]; then
    echo "Can't find the tool query2csv"
    exit 1
fi

#
# Open the SSH tunnel if it's not already open
#
_open_tunnel "$OTUNNEL"

#
# Gather and compute date information. Week numbers may start with a zero so
# we have to coerce them into base 10 from what will be presumed to be octal.
#
curweek="$((10#$(date +%V)))"
curdow="$(date +%u)"
woffset=$((weekno - curweek))
offset="$((woffset * 7 - curdow + 1)) days"
weekstart="$(date -d "$offset" +%F)"
weekfinish="$(date -d "$weekstart + 4 days" +%F)"

_DEBUG "Current week number: $curweek"
_DEBUG "Current day number: $curdow"
_DEBUG "Argument: $weekno"
_DEBUG "Week offset: $woffset"
_DEBUG "Day offset: $offset"
_DEBUG "Start of chosen week: $weekstart"
_DEBUG "End of chosen week: $weekfinish"

#
# Report what's happening in verbose mode
#
[ $VERBOSE -eq 1 ] && printf 'Processing week %s (%s to %s)\n' \
    "$weekno" "$weekstart" "$weekfinish"

#
# Make SQL
#
sql="select id from eps where date between '$weekstart' and '$weekfinish' order by id"

_DEBUG "SQL: $sql"

#
# Collect the shows
#
declare -a shows
mapfile -t shows < <(query2csv "$sql")

_DEBUG "shows: ${shows[*]}"

#
# Check we have enough shows, either exiting if not or continuing to check
# those we have.
#
if [[ ${#shows[*]} -ne 5 ]]; then
    echo "${red}Didn't find the expected number of shows for this week${reset}"
    if [[ $IGNORE -eq 0 ]]; then
        exit 1
    fi
fi

#
# Check the shows are on the IA
#
for show in "${shows[@]/#/hpr}"; do
    if ia list "$show" > /dev/null 2>&1; then
        echo "${green}$show has been uploaded${reset}"
    else
        echo "${red}$show has not been uploaded${reset}"
    fi
done

#
# All done
#
exit

# vim: syntax=sh:ts=8:sw=4:ai:et:tw=78:fo=tcrqn21