#! /bin/bash

function main() {
   set -e
   set -u

   cd "$(dirname "${BASH_SOURCE[0]}")"
   export GOPATH="$PWD/restic-go"

   if [ -z "${PASSWORD:-""}" ]; then
      read -sp "Password: " PASSWORD
      echo ""
   fi

   install

   configure

   local action="$1"
   shift
   case "$action" in
      clean ) clean_remote "$@"                 ;;
      backup ) backup "$@"                      ;;
      restore ) restore "$@"                    ;;
      forget ) fatal "Refusing custom forget"   ;;
      * )      RESTIC "$action" "$@"            ;;
   esac
}

function install() {
   mkdir -p "$GOPATH/bin/$(uname)"
   for i in ncw/rclone restic/restic; do
      local b="${i##*/}"
      if [ -e "$GOPATH/bin/$(uname)/$b" ]; then
         continue
      fi
      go get -u "github.com/$i" || true
      pushd "$GOPATH/src/github.com/$i"
      case "$i" in
         restic* )
            go run build.go
            mv "./$b" "$GOPATH/bin/$(uname)/$b"
         ;;
         * )
            go install
            mv "$GOPATH/bin/$b" "$GOPATH/bin/$(uname)/$b"
         ;;
      esac
      popd
   done
}

function configure() {
   mkdir -p "$PWD/config"
   if [ ! -e "$PWD/config/rclone" ]; then
      configure_rclone
   fi
   if [ ! -e "$PWD/config/restic" ]; then
      configure_restic
   fi
}

function configure_rclone() {
   RCLONE config create remote drive
   #RCLONE config create remote-enc crypt \
   #   remote remote:cloudly/restic \
   #   filename_encryption obfuscate \
   #   directory_name_encryption true \
   #   password $PASSWORD \
   #   password2 ""
}

function configure_restic() {
   RESTIC init
   touch "$PWD/config/restic"
}

function backup() {
   for arg in "$@"; do
      local real="$(realpath "$arg")"
      if [ "$real" == "${real#$HOME/}" ]; then
         log "Cowardly skipping $arg ($real) for not being under \$HOME ($HOME)"
         continue
      fi
      log "BACKUP $real"
      RESTIC backup \
         -e "**.sw*" \
         --tag "${real#$HOME/}" \
         "$real"
   done
}

function restore() {
   for arg in "$@"; do
      if [ -e "$arg" ] || [ -d "$arg" ]; then
         arg="$(realpath "$arg")"
      fi
      local latest="$(RESTIC snapshots --last | sort -k 2 | grep '20[0-9][0-9].[0-9][0-9].[0-9][0-9]' | tail -n 1)"
      local id="$(echo "$latest" | awk '{print $1}')"
      local path="$(echo "$latest" | awk '{print $5}')"
      local rpath="$(echo "$latest" | awk '{print $6}')"
      log "RESTORE $id as $HOME/$path as $HOME/$path-restore"
      rm -rf "$HOME/$path-"{dump,restore} 2> /dev/null || true
      mkdir -p "$HOME/$path-dump"
      RESTIC restore $id --target "$HOME/$path-dump"
      mv "$HOME/$path-dump/${rpath#/}" "$HOME/$path-restore"
      rm -rf "$HOME/$path-"{dump,old} || true
      if [ -d "$HOME/$path" ]; then
         mv "$HOME/$path" "$HOME/$path-old"
      fi
      mv "$HOME/$path-restore" "$HOME/$path"
   done
   clean_remote
}

function clean_remote() {
   RESTIC forget --prune --cleanup-cache --keep-last 2 --group-by host,tags "$@"
   RESTIC check
}

function RCLONE() {
   $GOPATH/bin/$(uname)/rclone --config=$PWD/config/rclone --ask-password=false "$@"
}

function RESTIC() {
   RESTIC_PASSWORD=$PASSWORD \
      $GOPATH/bin/$(uname)/restic \
      -r rclone:remote:cloudly/restic-plain/backup \
      -o rclone.program=$GOPATH/bin/$(uname)/rclone \
      -o rclone.args="serve restic --stdio --b2-hard-delete --drive-use-trash=false --config $PWD/config/rclone --bwlimit 26M --ask-password=false" \
      "$@"

      #-r rclone:remote-enc:backup
}

function log() {
   echo "$(date +%H:%M:%S): $@" >&2
}

function fatal() {
   log "$@"
   exit 1
}

if [ "$0" == "${BASH_SOURCE[0]}" ]; then
   SECONDS=0
   log "Start"
   main "$@"
   log "Stop ($?): $(python3 -c "print(int(10*$SECONDS/60)/10.0, 'minutes')")"
fi
