#!/usr/bin/bash
# Push/Pull VM-Disk-Image and Infos from server
set -eu

show_help() {
    cat << EOF >&2
Usage: $(basename "$0") command [args]"
command:
  push_file
  get_file
  get_image
  delete_outdated_image
  update_usage_information
EOF
}

get_torrent() {
    if [[ ! -f "${VM_SYSDIR}/${VM_NAME}.qcow2.torrent" ]]; then
      echo "No torrent-File found"
      exit 1
    fi
    cd "${VM_SYSDIR}"
    echo Size needed: $(get_image_size "${VM_NAME}.qcow2.torrent") " Bytes (VM-Image) + 5GB (spare)"
    echo Size available: $(df --block-size=1 --output=avail "${VM_SYSDIR}" | sed 1d)
    while [[ $(( $(get_image_size "${VM_NAME}.qcow2.torrent") + 15000000000 )) -gt $(df --block-size=1 --output=avail "${VM_SYSDIR}" | sed 1d) ]]; do
      echo "Not enough space to get ${VM_NAME}."
      FILENAME="$(head -1 vm_usage_information.txt)"
      if [[ -z $FILENAME ]]; then
        echo "No more old VM-files to delete. Unable to get ${VM_NAME}. Please contact system administrator."
	exit 1
      fi
      echo "Deleting $FILENAME"
      sudo vm-aria2 stop "$(basename "${FILENAME}" .qcow2)"
      rm -f "${FILENAME}"
      [[ -f "${VM_DIR}/${FILENAME}" ]] && rm -f "${VM_DIR}/${FILENAME}"
      sed -i -e 1d vm_usage_information.txt
    done
    lockfile="/tmp/sync-vm-${VM_NAME}.lock"
    if ! flock -n "$lockfile" echo "try to acquire lock"; then
      echo torrent seems to be in process.
      echo waiting for completion ...
      flock -w 3600 "$lockfile" echo "...completed"
      sleep 5
    else
      (
        if ! flock -n 200; then
	  echo "failed to acquire lock"
	  echo "Bitte noch einmal starten."
          echo "Beliebige Taste zum Beenden."
	  read -n 1
	  exit 1
        fi
	# stop aria2-seeding if running
        sudo vm-aria2 stop "${VM_NAME}"
        cd "${VM_SYSDIR}"
	# get image
	aria2c --seed-time=0 --dht-file-path="$DHTDAT" \
	       --dht-entry-point="${SEEDBOX_HOST}:${SEEDBOX_PORT}" \
	       "${VM_SYSDIR}/${VM_NAME}.qcow2.torrent"
	# and seed
        sudo vm-aria2 start "${VM_NAME}"
        if ! flock -u 200; then
	  echo failed to drop lock
	  exit 1
	fi
      ) 200>"$lockfile"
    fi
}


get_image_size() {
    torrentfile=$1
    length=$(aria2c -S "${torrentfile}"  | grep "Total Length" | \
		 sed -E -e 's/.*\(([0-9,]*)\)/\1/' -e 's/,//g')
    echo "$length"
}

delete_outdated_image() {
    cd "${VM_SYSDIR}"
    qcowsize=$(stat -c%s "${FILENAME}")
    if [[ -f "${FILENAME}.torrent" ]] && [[ "${qcowsize}" != $(get_image_size "${FILENAME}.torrent") ]]; then
      cat << EOF >&2

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Es wurde eine neueres VM-Image auf dem Server gefunden.
Das Herunterladen des Images via WLAN benötigt viel Zeit.
EOF
      read -rp "Soll das neue Image wirklich herunter geladen werden? j/n " answer
      if [[ "${answer,,}" ==  "j" ]]; then
        sudo vm-aria2 stop "${FILENAME%.qcow2}"
        rm -f "${FILENAME}"
      fi
    fi
}

update_usage_information() {
    cd "${VM_SYSDIR}"
    [[ -f vm_usage_information.txt ]] || ls -tr *.qcow2 > vm_usage_information.txt || touch vm_usage_information.txt
    FILENAME="$(basename $FILENAME)"
    echo sed -i "/${FILENAME}/d" vm_usage_information.txt
    sed -i "/${FILENAME}/d" vm_usage_information.txt
    echo "${FILENAME}" >> vm_usage_information.txt
}

get_file() {
   cd "${VM_SYSDIR}"
   curl --fail --noproxy "${SEEDBOX_HOST}" -o "${FILENAME}" \
	"http://${SEEDBOX_HOST}/aria2/${FILENAME}" || echo "File not found on seedbox"
}

push_file() {
   cd "${VM_SYSDIR}"
   uploadseed --server "${SEEDBOX_HOST}:${SEEDBOX_RPC_PORT}" --dht-port "${SEEDBOX_PORT}" \
	      --pwdfile "${SEEDBOX_PWFILE}" --no-cert "${FILENAME}"
}

########################

if [[ "$(id -nu)" != "lmnsynci" ]]; then
    echo "$(basename "$0") must be run as lmnsynci user"
    show_help
    exit 1
fi

source /etc/lmn/vm.conf

while getopts ':' OPTION; do
    case "$OPTION" in
        ?)
            show_help
            exit 1
            ;;
    esac
done

shift "$((OPTIND -1))"

# if less than one arguments supplied, display usage
if [[  $# -lt 1 ]]; then
    show_help
    exit 1
fi

command=$1
shift

case "$command" in
   push_file)
      for FILENAME in "$@"; do
	 push_file
      done
      ;;
   get_file)
      for FILENAME in "$@"; do
	 get_file
      done
      ;;
   get_image)
      for VM_NAME in "$@"; do
	 get_torrent
      done
      ;;
   delete_outdated_image)
      for FILENAME in "$@"; do
         delete_outdated_image
      done
      ;;
   update_usage_information)
      for FILENAME in "$@"; do
         update_usage_information
      done
      ;;
   *)
      show_help
      exit 1
      ;;
esac