#!/bin/sh
#
# linbo_download_image
# thomas@linuxmuster.net
# 20260625
#


#### functions begin ####

usage(){
  local RC="$1"
  echo
  echo "Downloads a newer imagefile from server into the cache, if there is one."
  echo
  echo "Usage: linbo_download_image <imagefile> | [help]"
  echo
  exit "$RC"
}


# download_torrent imagefile
download_torrent(){
  local imagefile="$1"
  local torrent="$imagefile".torrent
  [ -e "$torrent" ] || return 1
  source /etc/default/linbo-torrent || return 1
  # kill seeder if running
  linbo_kill_seeder "$torrent"
  rm -f "$imagefile"
  echo "Starting torrent download for $imagefile."
  aria2c $ARIA2C_GLOBAL_OPTS $ARIA2C_DWNLD_OPTS "$torrent" 2>&1 | awk '/^\[#/{print; fflush()}'
  RC="$?"
  #aria2c -c --console-log-level=notice --show-console-readout=true --summary-interval=1 \
  #  --enable-color=false --enable-dht=false --disable-ipv6=true --seed-time=0 "$torrent" ; RC="$?"
  # start seeder if download is complete
  [ "$RC" = "0" ] && linbo_seeder "$torrent"
  return "$RC"
}


# get_multicast_port file
get_multicast_port(){
  local file=""
  local serverport=""
  local relax=""
  while read file serverport relax; do
    if [ "$file" = "$1" ]; then
      echo "${serverport##*:}"
      return 0
    fi
  done </multicast.list
  return 1
}


# download_multicast port file
download_multicast(){
  echo "MULTICAST Download $INTERFACE($LINBOSERVER):$1 -> $2"
  echo "udp-receiver --log /tmp/linbo.log --nosync --nokbd --interface $INTERFACE --rcvbuf 4194304 --portbase $1 --file $2"
  interruptible udp-receiver --log /tmp/linbo.log --nosync --nokbd --interface "$INTERFACE" --rcvbuf 4194304 --portbase "$1" --file "$2" 2>&1 ; RC="$?"
  return "$RC"
}

#### functions end ####


# print help
[ -z "$1" -o "$1" = "help" ] && usage 0

# get environment
source /usr/share/linbo/shell_functions
echo "### $timestamp $(basename "$0") $@ ###"

# do not execute in localmode
if localmode; then
  echo "Local mode detected!"
  exit 0
fi

# check params
if [ -z "$1" ] || validip "$1"; then shift; fi
FILE="$1"

[ -z "$FILE" ] && usage 1

echo "### $(basename $0) $@"

source /conf/linbo &> /dev/null || exit 1

imagebase="$(basename "$FILE" | sed 's/\(.*\)\..*/\1/')"
imagetype="${FILE##*.}"
case "$imagetype" in
  qcow2|qdiff|iso) subdir="images/$imagebase/" ;;
  *) echo "Unknown image type $imagetype." ; exit 1 ;;
esac

infofile="${FILE}.info"
hashfile="${FILE}.hash"
torrentfile="${FILE}.torrent"

case "$downloadtype" in
  torrent) linbo_download "${subdir}${hashfile}" &> /dev/null ;;
  multicast) ;;
  *) downloadtype="rsync" ;;
esac

# check hash in case of torrent
if [ -s "$torrentfile" ]; then
  linbo_download "${subdir}${hashfile}" || exit 1
  serverhash="$(cat "$hashfile")"
  localhash="$(LANG=C btcheck -ni "$torrentfile" | grep ^'Torrent Hash' | awk '{print $4}')"
  [ "$serverhash" = "$localhash" ] || DOWNLOAD="yes"
fi

# check info file
if [ -z "$DOWNLOAD" -a -s "$infofile" -a -s "$FILE" ]; then
  # move info file
  mv -f "$infofile" "${infofile}.bak"
  # download infofile, first try from subdir
  if ! linbo_download "${subdir}${infofile}" &> /dev/null; then
    # remove differential image files if download fails
    # (means there is no diff image on the server)
    if [ "$imagetype" = "qdiff" ]; then
      rm -f "/cache/${FILE}"*
      return 0
    fi
    linbo_download "$infofile" &> /dev/null || exit 1
  fi
  # compare
  if ! diff -q "$infofile" "${infofile}.bak"; then
    echo "Info files of $FILE differ."
    DOWNLOAD="yes"
  fi
  rm -f "${infofile}.bak"
else
  DOWNLOAD="yes"
fi

# check FILE size
if [ -z "$DOWNLOAD" ]; then
  fs1="$(getinfo "$infofile" imagesize | sed 's|\"||g')"
  fs2="$(get_filesize "$FILE")"
  [ -z "$fs1" -o -z "$fs2" -o "$fs1" != "$fs2" ] && DOWNLOAD="yes"
fi

# download postsync and reg files in any case
for ext in postsync driverpostsync reg; do
  for base in "$FILE" "$imagebase"; do
    echo -n "Trying to download ${base}.${ext} ... "
    if linbo_download "${subdir}${base}.${ext}" &> /dev/null; then
      echo "Ok."
    else
      echo "not available."
    fi
  done
done

# download image related supplemental files
if [ -n "$DOWNLOAD" ]; then
  for ext in desc info; do
    echo -n "Trying to download ${FILE}.${ext} ... "
    if linbo_download "${subdir}${FILE}.${ext}" &> /dev/null; then
      echo "Ok."
    else
      echo "not available."
    fi
  done
# if image file is unchanged compared to server version end here
else
  echo "$FILE has not changed, nothing to do."
  # in case of downloadtype torrent, start seeding
  [ "$downloadtype" = "torrent" ] && linbo_seeder "$torrentfile"
  exit 0
fi

# download image file
RC=0
case "$downloadtype" in
  torrent)
    # download torrent file
    linbo_download "${subdir}$torrentfile" important &> /dev/null || RC="1"
    if [ "$RC" = "0" ]; then
      download_torrent "$FILE" || RC="1"
    fi
    ;;
  multicast)
    if [ -s /multicast.list ]; then
      MPORT="$(get_multicast_port "$FILE")"
      if [ -n "$MPORT" ]; then
        download_multicast "$MPORT" "$FILE" || RC="1"
      else
        echo "Cannot get multicast port, no multicast download possible." >&2
        RC=1
      fi
    else
      echo "multicast.list not found, no multicast download possible." >&2
      RC=1
    fi
    ;;
esac
# download per rsync also as a fallback if other download types failed
if [ "$RC" != "0" -o "$downloadtype" = "rsync" ]; then
  RC="0"
  linbo_download "${subdir}${FILE}" important &> /dev/null || RC="1"
fi

exit "$RC"
