#!/bin/bash
# ================================================================================
#
# UPDATE REPAIR USB STICK
#
# --------------------------------------------------------------------------------
# 2024-10-27  www.axel-hahn.de   v1.0
# ================================================================================

cd "$( dirname "$0" )" || exit 1

. vendor/color.class.sh || exit 1

FILE_LAST_SYNC=logs/last_sync2usb
FILE_SKIP_SYNC=logs/last_sync2usb_skip

SYNC_TARGET=
typeset -i iAge=0
typeset -i iAgeH=0
typeset -i iAgeD=0

# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------

function pageheader(){
clear
color.fg yellow
cat << EOH
     _________________________________________________________________________
____/

        Create/ Update Repair System
                                                                          ____
_________________________________________________________________________/


EOH
color.reset
}


function initializeUsbStick(){
    cat << EO_WELCOME
    WELCOME!

    This is a helper to create a repair system on a USB stick.

    With the repair system you can connect the backup repository if
    your system crashed and you have no local data anymore.

    💡 Hint:
    This is highly recommended if you have no system backup as image
    that can restore a complete system.

EO_WELCOME
    color.print green "Do you have a system backup as image? [y/N] "
    read -r answer

    if [ "$answer" = "y" ]; then
        echo "OK, I won't disturb you again."
        echo "Creating [$FILE_SKIP_SYNC] ..."
        date > "$FILE_SKIP_SYNC"
        echo "Bye."
        exit 0
    fi
    pageheader
}

# get age of a given file and fill global vars
#   iAge
#   iAgeH
#   iAgeD
# param  string  filename
function getAge(){
    local tsfile; typeset -i tsfile=0
    test -r "$1" && tsfile=$( date +%s -r "$1" )

    iAge=$( date +%s )-$tsfile
    iAgeH=$iAge/60/60
    iAgeD=$iAge/60/60/24
}

function showAge(){
  getAge "$1"
  if [ $iAgeD -gt 10000 ]; then
    echo "NEVER"
  else
    test $iAgeD -gt 0 && echo -n "$iAgeD days"
    test $iAgeD -eq 0 && test $iAgeH -gt 0 && echo -n "$iAgeH h"
    test $iAgeD -eq 0 && test $iAgeH -eq 0 && echo -n "$iAge s"
    echo " ago"
  fi
}

function _showUsbdrives(){
    local out; 
    out="$( df -H | grep media)"
    grep -q "." <<< "$out" && (df -H | head -1; echo "$out")
}

function _getSyncdir(){
    SYNC_TARGET="$( cat "$FILE_LAST_SYNC" 2>/dev/null | grep '^SYNC_TARGET=' | cut -f 2 -d '=' )"
}

# ----------------------------------------------------------------------
# MAIN
# ----------------------------------------------------------------------

pageheader

# ----------------------------------------------------------------------

if [ -f "$FILE_SKIP_SYNC" ]; then
    echo "Found the skip file [$FILE_SKIP_SYNC]."
    echo "The sync to USB will be skipped." 
    exit 0
fi

# ----------------------------------------------------------------------

if [ ! -f "$FILE_LAST_SYNC" ]; then
    initializeUsbStick
else
    echo -n "--- Last sync: "
    showAge "$FILE_LAST_SYNC"
    ls -l "$FILE_LAST_SYNC" 2>/dev/null
    echo
fi

# ----------------------------------------------------------------------

drivelist="$( _showUsbdrives )"

color.fg green
test -z "$drivelist" && color.fg red
cat <<USB
      ___
     |   |
     |___|
    /_____\\
    |     |
    | USB |
    |  _  |
    |_/=\_|


USB
color.reset

if [ -z "$drivelist" ]; then
    color.echo red "    ERROR: No USB drive found."
    echo "    Plug in your recovery usb stick and mount it before trying again."
    echo "    Onto the stick the backup client directory will be copied."
    echo "    You don't lose any data that are already there."
    echo
    exit 1
else
    echo "    USB drive found."
    echo
fi

# ----------------------------------------------------------------------

_getSyncdir

if [ -z "$SYNC_TARGET" ]; then
    echo "I expect that you added a usb drive where to sync the backup client."
    echo "    Onto the stick the backup client directory will be copied."
    echo "    You don't lose any data that are already there."
    echo
    echo "Select a target path (column Mounted on)"
    echo
    echo "$drivelist" | sed "s,^,    ,g"
    echo

    color.print green "Enter target path: "
    read -r mypath

    if [ -z "$mypath" ]; then
        color.echo red "No target path given. Exiting."
        exit 1
    fi

    if [ ! -d "$mypath" ]; then
        color.echo red "Target path [$mypath] does not exist. Exiting."
        exit 1
    fi

    subdir="$( hostname -f )__user__${USER}"
    SYNC_TARGET="$mypath/$subdir"

    echo "    Sync target: $SYNC_TARGET"
    echo
    color.print green "Please confirm - store the backup client in this path? [y/N] "
    read -r store
    if [ "$store" != "y" ] && [ "$store" != "Y" ]; then
        color.echo red "Target was not confirmeed. Aborting."
        exit 1
    fi

    mkdir -p "$SYNC_TARGET"
    pageheader

fi

# ----------------------------------------------------------------------

if [ ! -d "$SYNC_TARGET" ]; then
    color.echo red "Target path does not exist."
    echo
    echo "Content of $( dirname "$SYNC_TARGET" )"
    ls -l "$( dirname "$SYNC_TARGET" )"
    echo
    color.print green "Create subdir <$( basename "$SYNC_TARGET")> here? [y/N] "
    read -r answer
    if [ "$answer" != "y" ] && [ "$answer" != "Y" ]; then
        echo "Bye."
        exit 1
    fi
    mkdir -p "$SYNC_TARGET" || exit 2
fi

# ----------------------------------------------------------------------

echo "--- Syncing to USB stick [$SYNC_TARGET] ..." 

if rsync -ra --delete . "$SYNC_TARGET" ; then
    color.echo green "OK"
    echo "SYNC_TARGET=$SYNC_TARGET" > "$FILE_LAST_SYNC"
    echo
    echo "The sync was successful."
    echo "Unmount your USB stick and put it to a safe place."
    echo
else
    color.echo red "FAILED :-/"
    echo "Check the errors above. Then try again."
    echo    
    exit 1
fi

exit 0

# ----------------------------------------------------------------------
