#!/bin/bash
#
# starts tmux sessions for each valid torrent in LINBODIR
# thomas@linuxmuster.net
# 20221103
#

# read environment
#. /usr/share/linuxmuster/defaults.sh || exit 1
#THELPER=$LINBOSHAREDIR/linbo-torrenthelper.sh
THELPER=linbo-torrenthelper.sh
#. $LINBOSHAREDIR/helperfunctions.sh || exit 1
LINBOIMGEXT="qcow2 qdiff"
LINBOIMGDIR="/lmn/vm"
serverip="10.190.1.1"

# start of functions

# help message
usage(){
  echo
  echo "Info: vmimage-torrent manages the torrent tmux sessions of linbo images."
  echo
  echo "Usage:"
  echo " vmimage-torrent <start|stop|restart|reload|status|create|check> [image_name]"
  echo " vmimage-torrent attach <image_name|session_name>"
  echo
  echo "Note:"
  echo " * Only qcow2 & qdiff image files located below $LINBOIMGDIR are processed."
  echo " * The commands \"start\", \"stop\" and \"restart\" may have optionally an image"
  echo "   filename as parameter. In this case the commands are only applied to the tmux"
  echo "   session of the certain file. Without an explicit image filename the commands"
  echo "   were applied to all image file sessions currently running."
  echo " * An image filename parameter is mandatory with the commands \"check\", \"create\""
  echo "   and \"attach\"."
  echo " * \"check\" checks if the image file matches to the correspondig torrent."
  echo " * \"create\" creates/recreates the torrent of a certain image file."
  echo " * \"status\" shows a list of currently running torrent tmux sessions."
  echo " * \"attach\" attaches a torrent tmux session of a certain image. An image or"
  echo "   session name must be given as parameter."
  echo "   Press [CTRL+B]+[D] to detach the session again."
  echo " * \"reload\" is the identical to \"restart\" and is there for backwards compatibility."
  echo
  exit 1
}

# check torrent
check(){
  local image="$(basename "$IMGLIST")"
  local torrent="$image.torrent"
  local tdir="$(dirname "$IMGLIST")"
  cd "$tdir"
  echo "Checking $torrent ..."
  if ctorrent -c "$torrent"; then
    echo "Ok!"
  else
    echo "Failed!"
    exit 1
  fi
}

# creates torrent files
create(){
  local image="$(basename "$IMGLIST")"
  local tdir="$(dirname "$IMGLIST")"
  local torrent="${image}.torrent"
  local session="${torrent//./_}"
  # stop torrent service
  vmimage-torrent status | grep -q ^"$session" && vmimage-torrent stop "$IMGLIST"
  # skip already running torrents
  echo "Creating $torrent ..."
  cd "$tdir"
  rm -f "$torrent"
  if ctorrent -t -u "http://$serverip:6969/announce" -s "$torrent" "$image" ; then
    [ "$START" = "no" ] || vmimage-torrent start "$IMGLIST"
  else
    echo "Failed!"
    exit 1
  fi
}

# starts torrent tmux sessions
start(){
  local item
  local torrent
  local image
  local tdir
  local session
  for item in $IMGLIST; do
    image="$(basename "$item")"
    torrent="${image}.torrent"
    tdir="$(dirname "$item")"
    session="${torrent//./_}"
    cd "$tdir"
    if [ ! -s "$image" ]; then
      echo "Image $image does not exist! Skipping this torrent."
      continue
    fi
    # skip already running torrents
    if vmimage-torrent status | grep -qw ^"$session"; then
      echo "tmux session $session is already running."
      continue
    fi
    # create torrent file if there is none
    if [ ! -e "$torrent" ]; then
      START="no" vmimage-torrent create "$item" || continue
    fi
    echo -n "Starting tmux session $session ... "
    tmux new -ds "$session" "$THELPER $torrent ; exec $SHELL"
    sleep 1
    if vmimage-torrent status | grep -qw ^"$session"; then
      echo "Ok!"
    else
      echo "Failed!"
    fi
  done
}

stop(){
  if [ -n "$SESSION" ]; then
    vmimage-torrent status | grep -qw ^"$SESSION" || return
    tmux kill-session -t "$SESSION"
  else
    local item
    vmimage-torrent status | awk -F\: '{print $1}' | while read item; do
      tmux kill-session -t "$item"
    done
  fi
}

attach(){
  if ! tmux list-sessions | grep -qw "$SESSION"; then
    echo "There is no session $SESSION."
    exit 1
  fi
  echo "Hint: Detach tmux session with [CTRL+B]+[D]."
  sleep 3
  tmux attach -t "$SESSION"
}

status(){
  tmux list-sessions | grep _torrent
}

find_images(){
  local search="$(basename "$1")"
  if [ -n "$search" ]; then
    find "$LINBOIMGDIR" -maxdepth 2 -name "$search"
    return
  fi
  local IMGLIST
  for search in $LINBOIMGEXT; do
    IMGLIST="$IMGLIST $(find "$LINBOIMGDIR" -maxdepth 2 -name \*.$search)"
  done
  # trim leading and trailing spaces
  echo $IMGLIST | awk '{$1=$1};1'
}

# end of functions

# check parameters
if [ -n "$2" ] ; then
  # trap torrent parameter
  image="${2/.torrent/}"
  case "$image" in
    *.qcow2|*.qdiff)
      if [ -e "$image" ]; then
        IMGLIST="$image"
      else
        IMGLIST="$(find_images "$image")"
      fi
      if [ ! -e "$IMGLIST" ]; then
        echo "Image file $(basename $image) not found."
        usage
      fi
      filename="$(basename "$IMGLIST")"
      SESSION="${filename//./_}_torrent"
      ;;
    *_torrent)
      if [ "$1" = "attach" ]; then
        SESSION="$image"
      else
        usage
      fi
      ;;
    *) usage ;;
  esac
else
  case "$1" in
    stop|status) ;;
    attach|check|create) usage ;;
    *)
      IMGLIST="$(find_images)"
      if [ -z "$IMGLIST" ]; then
        echo "No linbo images found."
        exit 0
      fi
      ;;
  esac
fi

case "$1" in
  start) start ;;
  stop) stop ;;
  restart|reload) stop ; start ;;
  status) status ;;
  create) create ;;
  check) check ;;
  attach) attach ;;
  *) usage ;;
esac

exit 0
