#!/bin/bash

# Settings
PATCHES_DIR=patches
GIT_DIR=git
DEST_DIR=sources
WORK_DIR=work
PATCH_LOG=`readlink -f "long.log"`
SHORT_LOG=`readlink -f "short.log"`
SKIP_BAD_PATCHES="${SKIP_BAD_PATCHES:-0}"

# Init
term_width=`tput cols`

die() { echo " !!!ERROR: ${1}"; exit 1; }
_epatch_assert() { local _pipestatus=${PIPESTATUS[*]}; [[ ${_pipestatus// /} -eq 0 ]] ; }

prepare_dir() {
  [ -z "${1}" ] && die "dir must not be empty";
  [ ! -e "${1}" ] && mkdir "${1}"
  [ ! -d "${1}" ] && die "can't prepare dir ${1}"
}

unpack_git() {
  ( cd "${GIT_DIR}"; git archive --format=tar master ) \
  	| ( cd "${1}" ; tar xf - )
  ( cd "${GIT_DIR}/iris"; git archive --format=tar master ) \
  	| ( cd "${1}/iris" ; tar xf - )
  ( cd "${GIT_DIR}/src/libpsi"; git archive --format=tar master ) \
  	| ( cd "${1}/src/libpsi" ; tar xf - )
}

spatch() {
  popts=""
  PATCH_TARGET="${1}"

  if [ ! -f $PATCH_TARGET ]
  then
    echo "patch '${PATCH_TARGET}' doesn't exist"
    exit 1
  fi

  echo -n " * applying ${PATCH_TARGET}..."

  count=0
  while [ "${count}" -lt 5 ]; do
    echo " * trying patch -p${count} ${popts} --dry-run -f" >> $PATCH_LOG
    if (cat ${PATCH_TARGET} | patch -p${count} ${popts} --dry-run -f ; _epatch_assert) >> $PATCH_LOG 2>&1
    then
      cat ${PATCH_TARGET} | patch -p${count} ${popts} >> $PATCH_LOG 2>&1
      _epatch_assert
      if [ "$?" -ne 0 ]
      then
        echo "A dry-run of patch command succeeded, but actually"
        echo "applying the patch failed!"
        count=5
      fi
      break;
    fi
    count=$((count + 1))
  done

  if [ $count -ne 5 ]
  then
     echo "done"
     echo "${PATCH_TARGET}" >> $SHORT_LOG
     return 0
  else
     [ "${SKIP_BAD_PATCHES}" = "1" ] && echo "fail. skip it.";
     [ "${SKIP_BAD_PATCHES}" = "1" ] && return 0
     echo -e "fail\nsee log here ${PATCH_LOG}";
  fi
  return 1
}


PATCHES=`ls -1 "${PATCHES_DIR}"/*diff 2>/dev/null`
[ -z "${PATCHES}" ] && die "patches not found in ${PATCHES_DIR}"
[ -d "${GIT_DIR}/.git" ] || die "${GIT_DIR} is not git repo"


prepare_dir "${DEST_DIR}"
prepare_dir "${WORK_DIR}"


ZENITY_LIST=`echo "${PATCHES}" | sed 's/.*/FALSE \0/'`
UP_TO=`zenity --title 'Patch selector' --text 'Apply patches up to?' \
	--list --radiolist --column '' --column Patch --height 440 \
	--width 600 ${ZENITY_LIST}`
[ "$?" != 0 ] && die "aborted"

echo "patches will be applied up to ${UP_TO}"

unpack_git "${DEST_DIR}"
unpack_git "${WORK_DIR}"
touch "${SHORT_LOG}"

if [ ! -z "${UP_TO}" ]
then
  for p in $PATCHES; do
     fp=$(readlink -f "${p}")
     ( cd "${WORK_DIR}"; spatch "${fp}" )
     [ "$?" = 0 ] || die "can't continue"
     [ "${p}" = "${UP_TO}" ] && [ "$1" = "-e" ] && break
     ( cd "${DEST_DIR}"; spatch "${fp}" )
     [ "$?" = 0 ] || die "can't continue"
    [ "${p}" = "${UP_TO}" ] && break;
  done
fi

( cd "${DEST_DIR}"; sed 's/<!--\(.*plugins.*\)-->/\1/' -i psi.qc; qconf; )
( cd "${WORK_DIR}"; sed 's/<!--\(.*plugins.*\)-->/\1/' -i psi.qc; qconf; ./configure --disable-growl --disable-bundled-qca \
  --debug --prefix=/usr --qtdir=/usr --enable-plugins )

[ -f psi.pro.user ] && cp psi.pro.user "${WORK_DIR}"
