#!/bin/bash
#
# convert cloop image to qcow2 format
# thomas@linuxmuster.net
# 20250326
#

# read environment
source /usr/share/linuxmuster/helperfunctions.sh || exit 1

usage(){
  echo
  echo "Usage: `basename $0` <cloop_image> [output_directory]"
  echo
  echo "Note:"
  echo " * If the cloop image is given without a path and resides not in the"
  echo "   current directory then $LINBODIR is assumed as input directory."
  echo " * If output directory is omitted the output file is created in a"
  echo "   subdirectory of $LINBOIMGDIR."
  echo " * Make sure there is enough space in the output directory."
  echo
  exit 1
}

# check inputfile
CLOOPFILE="$1"
inputdir="$(dirname $CLOOPFILE)"
if [ "$inputdir" = "." -a ! -e "$CLOOPFILE" ]; then
  # assume inputfile is in LINBODIR
   CLOOPFILE="$LINBODIR/$CLOOPFILE"
fi
if [ ! -s "$CLOOPFILE" -o "${CLOOPFILE##*.}" != "cloop" ]; then
  [ -z "$CLOOPFILE" ] && CLOOPFILE="[none]"
  echo "$CLOOPFILE is no cloop image."
  usage
fi

# check output directory
imagename="$(basename "$CLOOPFILE")"
subdir="${imagename/.cloop/}"
if [ -d "$2" ]; then
  TARGETDIR="$2"
elif [ -z "$2" ]; then
  TARGETDIR="$LINBOIMGDIR/$subdir"
  mkdir -p "$TARGETDIR"
else
  echo "Output directory $2 does not exist!"
  usage
fi

# output file
QCOW2FILE="${CLOOPFILE/.cloop/.qcow2}"
if [ -n "$TARGETDIR" ]; then
  QCOW2FILE="$TARGETDIR/$(basename $QCOW2FILE)"
else
  TARGETDIR="$(dirname "$QCOW2FILE")"
fi

# get sizes from infofile
infofile="${CLOOPFILE}.info"
if [ -s "$infofile" ]; then
  psize_kb="$(grep ^partitionsize "${CLOOPFILE}.info" | awk -F\= '{print $2}')"
  psize="$(( $psize_kb / 1024 / 1024 ))"
  isize_b="$(grep ^imagesize "${CLOOPFILE}.info" | awk -F\= '{print $2}')"
  isize="$(( $isize_b / 1024 / 1024 / 1024 ))"
  isize_kb="$(( $isize_b / 1024 ))"
fi

# get image size from file
if [ -z "$isize" ]; then
  isize_b="$(stat -t "$CLOOPFILE" | awk '{print $2}')"
  isize="$(( $isize_b / 1024 / 1024 / 1024 ))"
fi

sizefree_kb="$(LANG=C df -P "$TARGETDIR" | tail -1 | awk '{print $4}')"
if [ $isize_kb -gt $sizefree_kb ]; then
  echo "Not enough free space in $TARGETDIR, needed ${isize_kb}K, available ${sizefree_kb}K!"
  exit 1
fi

isize="${isize}G"
psize="${psize}G"

echo "### $(basename $0) ###"
echo "Input file    : $CLOOPFILE"
echo "Output file   : $QCOW2FILE"
echo "Image size    : $isize"
echo "Partition size: $psize"
echo

# convert raw image
echo "Converting $(basename $CLOOPFILE) -> $(basename $QCOW2FILE) ..."
if ! qemu-img convert -p -c -f cloop -O qcow2 "$CLOOPFILE" "$QCOW2FILE"; then
  rm -f "$QCOW2FILE"
  "Conversion to qcow2 image failed!"
  exit 1
fi

# copy supplemental files
imagebase="${QCOW2FILE/.qcow2/}"
for i in info desc postsync prestart reg macct; do
  srcfile="${CLOOPFILE/.cloop/}.$i"
  [ -e "$srcfile" ] || srcfile="${CLOOPFILE}.$i"
  [ -e "$srcfile" ] || continue
  case "$i" in
    info|desc|macct) cp "$srcfile" "${QCOW2FILE}.$i" ;;
    *) cp "$srcfile" "${imagebase}.$i" ;;
  esac
done

# change to targetdir
if [ "$TARGETDIR" != "." ]; then
  cd "$TARGETDIR"
  QCOW2FILE="$(basename "$QCOW2FILE")"
fi

# update info file
infofile="${QCOW2FILE}.info"
if [ -s "$infofile" ]; then
  echo "Updating $infofile."
  sed -i 's|.cloop|.qcow2|g' "$infofile"
  tstamp="$(date +%Y%m%d%H%M)"
  sed -i "s|^timestamp=.*|timestamp=$tstamp|" "$infofile"
  size="$(stat -t "$QCOW2FILE" | awk '{print $2}')"
  sed -i "s|^imagesize=.*|imagesize=$size|" "$infofile"
else
  echo "Skipping update for missing $infofile."
fi

# create torrent file
echo "Creating $QCOW2FILE.torrent ..."
ctorrent -t -u http://"$serverip":6969/announce -s "$QCOW2FILE.torrent" "$QCOW2FILE"

# restart linbo-torrent if file is created in LINBOIMGDIR
stringinstring "$LINBOIMGDIR" "$TARGETDIR" && linbo-torrent restart
