#!/bin/bash -
#===============================================================================
#
#         FILE: delete_ia_item
#
#        USAGE: ./delete_ia_item episode
#
#  DESCRIPTION: Deletes an uploaded item on the IA. The item (identifier)
#               can't be deleted entirely but it can be stripped of contents
#               and metadata and left in a 'Reserved' state so the slot can be
#               reused.
#
#      OPTIONS: ---
# REQUIREMENTS: ---
#         BUGS: ---
#        NOTES: ---
#       AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
#      VERSION: 0.0.3
#      CREATED: 2022-05-08 19:40:37
#     REVISION: 2022-08-14 23:09:51
#
#===============================================================================

set -o nounset                              # Treat unset variables as an error

VERSION="0.0.3"

SCRIPT=${0##*/}
# DIR=${0%/*}

STDOUT="/dev/fd/2"

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

#
# Colour codes
#
define_colours

#
# Make temporary files and set traps to delete them
#
TMP1=$(mktemp) || { echo "$SCRIPT: creation of temporary file failed!"; exit 1; }
trap 'cleanup_temp $TMP1' SIGHUP SIGINT SIGPIPE SIGTERM EXIT

#===  FUNCTION  ================================================================
#         NAME: _DEBUG
#  DESCRIPTION: Writes messages 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: Report usage
#   PARAMETERS: 1       [optional] exit value
#      RETURNS: Nothing
#===============================================================================
_usage () {
    local -i res="${1:-0}"

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

Usage: ./${SCRIPT} [-h] [-d {0|1}] episode

Deletes an uploaded item on the IA. The item (identifier) can't be deleted
entirely but it can be stripped of contents and metadata and left in
a 'Reserved' state so the slot can be reused.

Options:
  -h                    Print this help
  -d 0|1                Dry run: -d 1 (the default) runs the script in dry-run
                        mode where nothing is moved but the actions that
                        will be taken are reported; -d 0 turns off dry-run
                        mode and the actions will be carried out.

Arguments:
   episode              Defines the episode (IA identifier) to be deleted from
                        archive.org. These identifiers are in the format
                        'hprNNNN' where 'NNNN' is a number with leading
                        zeroes, and 'hpr' is mandatory.

                        The script attempts to reformat incorrect identifiers
                        before giving up. The missing 'hpr' is added, and
                        missing leading zeroes are inserted. Thus '42' and
                        'hpr42' become 'hpr0042'.

Environment variables:
  delete_ia_item_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
    ./delete_ia_item 3594        # Run in (default) dry-run mode
    ./delete_ia_item -d1 3594    # Run in (explicit) dry-run mode
    ./delete_ia_item -d0 3594    # Live mode

    delete_ia_item_DEBUG=1 ./delete_ia_item 3594
                                 # Run in dry-run mode with debugging enabled

endusage
    exit "$res"
}

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

#
# Configure depending whether local or on borg
#
case $HOSTNAME in
    hprvps|marvin|borg)
        BASEDIR="$HOME/IA" ;;
    i7-desktop)
        BASEDIR="$HOME/HPR/IA" ;;
    *)
        echo "Wrong host!"; exit 1 ;;
esac

cd "$BASEDIR" || { echo "Can't cd to $BASEDIR"; exit 1; }

#
# Directories and files
#
LOGS="$BASEDIR/logs"
LOGFILE="$LOGS/$SCRIPT.log"

#
# Debug mode. Invoke it with: 'delete_ia_item_DEBUG=1 ./tidy_uploaded'
#
DEBUGVAR="${SCRIPT}_DEBUG"
DEBUG="${!DEBUGVAR:-0}"
[[ $DEBUG -eq 1 ]] && echo "Debug mode"

#
# File of processed shows
#
PROCFILE="$BASEDIR/.${SCRIPT}.dat"
[ -e "$PROCFILE" ] || touch "$PROCFILE"

#
# Prerequisites
#
jq=$(command -v jq)
[ -z "$jq" ] && { echo "Needs the 'jq' JSON filter"; exit 1; }
ia=$(command -v ia)
[ -z "$ia" ] && { echo "Needs the 'ia' Internet Archive script"; exit 1; }

#
# Process options
#
while getopts :d:h opt
do
    case "${opt}" in
        d) DRYRUN=$OPTARG;;
        h) _usage 0;;
        *) echo "** Unknown option"
           _usage 1;;
    esac
done
shift $((OPTIND - 1))

DRYRUN=${DRYRUN:-1}
if [[ $DRYRUN -ne 0 && $DRYRUN -ne 1 ]]; then
    echo "** Use '-d 0' or '-d 1'"
    _usage 1
fi
[[ $DRYRUN -eq 1 ]] && echo "Dry run mode"

#
# Should have only one argument
#
if [[ $# != 1 ]]; then
    echo "${red}${SCRIPT} takes one argument${reset}"
    _usage 1
fi

#
# Collect the argument and clean and validate it, forcing leading zeroes if
# needed
#
item="${1:-}"
item="${item,,}"
item="${item## }"
item="${item%% }"
if [[ $item =~ ^(hpr)?([0-9]{1,4})$ ]]; then
    printf -v item 'hpr%04i' "${BASH_REMATCH[2]}"
else
    echo "${red}Invalid episode specification: '$item'${reset}"
    echo "${yellow}Use hprNNNN format with leading zeroes${reset}"
    _usage 1
fi

_DEBUG "Dry run:     $DRYRUN"
_DEBUG "Item chosen: $item"

#
# Check the item exists on the IA and if it does collect metadata and parse
# out the items we need.
#
_DEBUG "Testing IA for existence of $item"
if ia list "$item" > /dev/null 2>&1; then
    ia metadata "$item" > "$TMP1"

    # This one's an array but we want a CSV list.
    # TODO: Not sure this works with tags containing spaces
    # shellcheck disable=SC2046
    subject="$(jq -r '.metadata.subject | @csv' "$TMP1")"
    subject="${subject//\"\"\"/\"}"

    creator="$(jq -r '.metadata.creator' "$TMP1")"

    date="$(jq -r '.metadata.date' "$TMP1")"

    _DEBUG "subject:     $subject"
    _DEBUG "creator:     $creator"
    _DEBUG "date:        $date"
else
    echo "${red}The requested item '$item' is not on archive.org${reset}"
    exit 1
fi

#
# Either pretend to do stuff in dry-run mode or do it for real, but with
# confirmation first.
#
if [[ $DRYRUN -eq 1 ]]; then
    echo "${yellow}Would have deleted item $item${reset}"
    echo "Commands:"
    echo "${blue}ia delete $item --all --no-backup${reset}"
    echo "${blue}ia metadata $item --modify=title:\"Reserved\"${reset}"
    echo "${blue}ia metadata $item --modify=description:\"Reserved\"${reset}"
    echo "${blue}ia metadata $item --remove=creator:\"$creator\"${reset}"
    echo "${blue}ia metadata $item --remove=date:$date${reset}"
    echo "${blue}ia metadata $item --remove=subject:'$subject'${reset}"
    echo
    echo "${blue}Would have removed any cache entry found${reset}"
else
    echo "${red}About to delete item $item.${reset}"
    if yes_no "OK to continue? %s " "N"; then
        # Not yet tested. Can't be until we have a need! Note that the quoted
        # items will not be shown as such using this form of 'echo'.
        # echo "Commands are being displayed, not run, until testing is complete"
        #
        # Now tested, and looking good
        #
        ia delete "$item" --all --no-backup
        ia metadata "$item" --modify=title:"Reserved"
        ia metadata "$item" --modify=description:"Reserved"
        ia metadata "$item" --remove=creator:"$creator"
        ia metadata "$item" --remove=date:"$date"
        ia metadata "$item" --remove=subject:"$(printf "'%s'" "$subject")"

        #
        # Ensure the show is not marked as "processed" in the cache. We need
        # 'grep' to determine if there's anything to do since 'sed' can't do
        # this apparently.
        #
        if grep -q -E '^'"$item"'$' "$PROCFILE"; then
            sed -i -e '/^'"$item"'$/d' "$PROCFILE"
            echo "${yellow}$item removed from cache${reset}"
        else
            echo "${yellow}$item not found in cache${reset}"
        fi

        #
        # Log this item
        #
        echo "$(date +%Y%m%d%H%M%S) deleted $item" >> "$LOGFILE"
    else
        echo "${red}Item not deleted. Aborting.${reset}"
    fi
fi

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