#!/bin/bash
RECORDVM_DATA=/var/makedist/recordvm
#VBOX=1
VBOX_VMNAME="openmamba-recordvm"
X_DISPLAY=4
EXECUTION_TIME=200
VIDEO_EXT=.flv
VIDEO_EXT2=.ogv

function usage()  {
   echo "Usage:"
   echo "recordvm.sh iso_path [--only-recreate-images] [-h]"
   echo
   exit 1
}

opts=($@)

while test -n "$1" ; do
   case $1 in
      "--only-recreate-images") ONLY_RECREATE_IMAGES=1;;
      "-h") usage; exit 0 ;;
       *) if [ -z "$ISO_PATH" ]; then
             ISO_PATH=$1
          else
             echo "Error: extra argument $1 specified; aborting."
             usage
             exit 1
          fi
    esac
    shift
done

[ "$ISO_PATH" ] || {
   echo "Error: ISO path was not specified; aborting."
   usage
   exit 1
}

ISO_DIR=`dirname $ISO_PATH`
ISO_NAME=`basename $ISO_PATH`
ISO_ARCH=`echo $ISO_NAME | sed "s|.*\.\([A-Za-z0-9_]*\)\.iso|\1|"`

[ -e $ISO_PATH ] || {
   echo "Error: file $ISO_PATH does not exist; aborting."
   exit 1
}

if [ -e $ISO_DIR/latest-is-milestone*.txt ]; then
   ISO_VERSION=`ls $ISO_DIR/latest-is-milestone[0-9]*-*.txt 2>/dev/null| sed "s/.*latest-is-milestone[0-9]*-\(.*\)\.txt/\1/"`
elif [ -e $ISO_DIR/latest-is-*.txt ]; then
   ISO_VERSION=`ls $ISO_DIR/latest-is-*.txt 2>/dev/null| sed "s/.*latest-is-\(.*\)\.txt/\1/"`
fi

[ "$ISO_VERSION" ] || {
   echo "makedist-recordvm: ERROR: unable to find latest version file in $ISO_DIR; running in view mode only."
   VIEWMODE=1
}

echo $ISO_NAME | grep $ISO_VERSION >/dev/null || {
   echo "makedist-recordvm: ERROR: iso file passed as input does not contain versione; running in view mode only."
   VIEWMODE=1
}

if [ ! "$ONLY_RECREATE_IMAGES" ]; then
   echo "Preparing ISO image $ISO_PATH"
   ln -sf $ISO_PATH $RECORDVM_DATA/recordvm.iso
   [ -e /tmp/.X$X_DISPLAY-lock ] && X_PID=`cat /tmp/.X$X_DISPLAY-lock`
   if [ "$X_PID" ]; then
      echo "Warning: an X server seems already running on display $X_DISPLAY with pid $X_PID; killing."
      kill -9 $X_PID
   fi
   echo "Starting virtual machine for $ISO_PATH"
   export HOME=$RECORDVM_DATA
   xinit -- :$X_DISPLAY &

   if [ "$VBOX" ]; then
      trap "VBoxManage controlvm $VBOX_VMNAME poweroff" INT QUIT TSTP

      sleepcnt=0
      while true; do
         if [ "`VBoxManage list runningvms | grep $VBOX_VMNAME`" ]; then
            break
         fi
         sleep 1
         if [ $sleepcnt -gt 20 ]; then
            echo "VirtualBox did not start; aborting."
            exit 1
         fi
         let sleepcnt=sleepcnt+1
      done
      WINID=`xwininfo -display :$X_DISPLAY -name "$VBOX_VMNAME - Oracle VM VirtualBox" 2>/dev/null |grep "Window id:"| sed "s|.*Window id: \([0-9a-fx]*\).*|\1|"`
      VOFFSET=0
      VBoxManage controlvm $VBOX_VMNAME reset
   else
      sleepcnt=0
      while true; do
#         WINID=`xwininfo -display :$X_DISPLAY -name "QEMU (qemu-recordvm)" 2>/dev/null |grep "Window id:"| sed "s|.*Window id: \([0-9a-fx]*\).*|\1|"`
         WINID=`xwininfo -display :$X_DISPLAY -root -children 2>/dev/null | grep qemu-recordvm | awk '{ print $1; }' 2>/dev/null`
         [ "$WINID" ] && break
         if [ $sleepcnt -gt 20 ]; then
            echo "qemu did not start; aborting."
            exit 1
         fi
         let sleepcnt=sleepcnt+1
         sleep 1
      done
      # since qemu 1.5 skip top menu when capturing
      VOFFSET=24
   fi

   echo "Windowid is: $WINID"

   if [ ! "$VIEWMODE" ]; then
      echo "Capturing window output"
      mkdir -p $ISO_DIR/preview/
      DBUS_SESSION_BUS_ADDRESS= HOME=$RECORDVM_DATA DISPLAY=:$X_DISPLAY xvidcap \
         --cap_geometry 1024x768+0+$VOFFSET \
         --verbose 2 --gui no --audio no \
         --time $EXECUTION_TIME --file $ISO_DIR/preview/${ISO_NAME}${VIDEO_EXT} \
         --quality 100 >>$RECORDVM_DATA/recordvm.log
   else
      sleep $EXECUTION_TIME
   fi

   echo "Powering off VM"
   if [ "$VBOX" ]; then
      # Virtualbox
      VBoxManage controlvm $VBOX_VMNAME poweroff &

      count=0
      while [ "`pidof VBoxManage`" ]; do
         let count=count+1
         sleep 1
         if [ $count -gt 60 ]; then
            killall -9 VBoxManage
            break
         fi
      done
   else
      # Qemu
      if [ "$WINID" ]; then
         xkill -id $WINID -display :$X_DISPLAY || true
      fi
      sleep 10
      # workaround for safety
      QEMU_PID=`pidof qemu-system-x86_64`
      if [ "$QEMU_PID" ]; then
         for p in $QEMU_PID; do
            grep qemu-recordvm /proc/$p/cmdline && kill -9 $p
         done
      fi
      # FIXME: sleep here as a workaround attempt for script aborting sometimes
   fi
   [ -e /tmp/.X$X_DISPLAY-lock ] && X_PID=`cat /tmp/.X$X_DISPLAY-lock`
   if [ "$X_PID" ]; then
      echo "Warning: X server seems to be still running on display $X_DISPLAY with pid $X_PID; killing."
      kill -9 $X_PID
   fi
fi

if [ ! "$VIEWMODE" ]; then
   echo "Creating preview images"
   rm -f $ISO_DIR/preview/image-${ISO_ARCH}-*.jpg
   ffmpeg -y -i $ISO_DIR/preview/$ISO_NAME${VIDEO_EXT} -r 0.1 -f image2 $ISO_DIR/preview/image-${ISO_ARCH}-%02d.jpg >/dev/null || \
      echo "ERROR: ffmpeg exited with code: $?"
   for i in `seq 22 -1 1`; do
      f=`printf %02d $i`
      convert -resize 50x40 $ISO_DIR/preview/image-${ISO_ARCH}-$f.jpg $ISO_DIR/preview/image-${ISO_ARCH}-$f-50x40.jpg || \
         echo "ERROR: convert exited with code: $?"
   done
   for i in `seq 22 -1 1`; do
      f=`printf %02d $i`
      rm -f $ISO_DIR/preview/preview-${ISO_ARCH}-*.jpg
      [ -e $ISO_DIR/preview/image-${ISO_ARCH}-$f.jpg ] && {
         convert -resize 320x200 $ISO_DIR/preview/image-${ISO_ARCH}-$f.jpg $ISO_DIR/preview/preview-${ISO_ARCH}-$ISO_VERSION.jpg
         ln -sf preview-${ISO_ARCH}-$ISO_VERSION.jpg $ISO_DIR/preview/preview-${ISO_ARCH}.jpg
         convert -resize 400x300 $ISO_DIR/preview/image-${ISO_ARCH}-$f.jpg $ISO_DIR/preview/preview-${ISO_ARCH}-$ISO_VERSION-400x300.jpg
         ln -sf preview-${ISO_ARCH}-$ISO_VERSION-400x300.jpg $ISO_DIR/preview/preview-${ISO_ARCH}-400x300.jpg
         break
      }
   done

   if [ ! "$ONLY_RECREATE_IMAGES" ]; then
      echo "Creating ${VIDEO_EXT2} video from ${VIDEO_EXT}"
      ffmpeg2theora -o $ISO_DIR/preview/$ISO_NAME${VIDEO_EXT2} $ISO_DIR/preview/$ISO_NAME${VIDEO_EXT} >/dev/null

      # cleanup old files
      for f in `ls $ISO_DIR/preview/*.${ISO_ARCH}.*${VIDEO_EXT}`; do
         [ "$f" = "$ISO_DIR/preview/$ISO_NAME${VIDEO_EXT}" ] || rm -f $f
      done
      for f in `ls $ISO_DIR/preview/*.${ISO_ARCH}.*${VIDEO_EXT2}`; do
         [ "$f" = "$ISO_DIR/preview/$ISO_NAME${VIDEO_EXT2}" ] || rm -f $f
      done

      ln -snf $ISO_NAME${VIDEO_EXT} $ISO_DIR/preview/${ISO_NAME/-$ISO_VERSION}${VIDEO_EXT}
      ln -snf $ISO_NAME${VIDEO_EXT2} $ISO_DIR/preview/${ISO_NAME/-$ISO_VERSION}${VIDEO_EXT2}      

   fi
fi

echo "Done."
exit 0