#! /bin/bash

. /etc/profile

if [ -e "$HOME/.profile" ]; then
  . "$HOME/.profile"
fi

CONFDIR=

STRIP=
UPDATE=true
SIGN=true
CLEAN=true

while [ -n "$1" ]; do
  case $1 in
    -[cC])
      if [ -z "$2" ]; then
        echo "-c expects a configuration dir as argument"
        exit 1
      fi
      CONFDIR=$2
      shift 2
    ;;
    --nostrip)
      STRIP=false
      shift 1
    ;;
    --strip=false)
      STRIP=false
      shift 1
    ;;
    --strip=true)
      shift 1
    ;;
    --strip=*)
      echo "Invalid argument to --strip"
      exit 1
    ;;
    --noupdate)
      UPDATE=false
      shift 1
    ;;
    --update=false)
      UPDATE=false
      shift 1
    ;;
    --update=true)
      UPDATE=true
      shift 1
    ;;
    --update=*)
      echo "Invalid argument to --update"
      exit 1
    ;;
    --nosign)
      SIGN=false
      shift 1
    ;;
    --sign=false)
      SIGN=false
      shift 1
    ;;
    --sign=true)
      SIGN=true
      shift 1
    ;;
    --sign=*)
      echo "Invalid argument to --sign"
      exit 1
    ;;
    --noclean)
      CLEAN=false
      shift 1
    ;;
    *)
      echo "Unknown option: $1"
      exit 1
    ;;
  esac
done

init()
{
  if [ -n "$0" -a "${0:0:1}" = "/" ]; then
    local dir="${0%/*}"
  else
    local dir="`pwd`/${0%/*}"
  fi
  if [ -z "$CONFDIR" ]; then
    echo "Need to pass configuration with -c argument"
    exit 1
  else
    if [ "${CONFDIR:0:1}" != "/" ]; then
      CONFDIR="$dir/../config/$CONFDIR"
    fi
    CONFDIR=`realpath -m "$CONFDIR"`
  fi
  if echo "$CONFDIR" | grep ' ' >/dev/null 2>&1; then
    echo "Spaces in config dir are now allowed"
    exit 1
  fi
  if [ ! -f "$CONFDIR/config" ]; then
    echo "Can't find master config."
    echo "  pwd: `pwd`"
    echo "  \$0: $0"
    echo "  Configuration directory: $CONFDIR"
    echo "Aborting."
    exit 1
  fi
  cd "$dir/.."
  export PREFIX=`pwd`
  echo "Setting prefix to $PREFIX"
  cd "$dir"
  return 0
}

init || exit 1

. "$CONFDIR/config"
. log.sh
. updatesrc.sh
. readfile.sh
. readhosts
. readpackages
. buildspawn.sh
. makedist.sh
. filter.sh
. prebuild.sh
. postbuild.sh

echo "#! /bin/sh" > "$PREFIX/clientscripts/parameters"
echo -e "\\n# This file is auto-generated by nightlygen\\n" >> "$PREFIX/clientscripts/parameters"
chmod +x "$PREFIX/clientscripts/parameters"
echo "export STRIP=$STRIP" >> "$PREFIX/clientscripts/parameters"
echo "export SIGN=$SIGN" >> "$PREFIX/clientscripts/parameters"

clean_files()
{
  if [ -d "$WORKDIR" ]; then
    cd "$WORKDIR" #To get out of a subdir
    rm -rf "$WORKDIR/dist"
    rm -rf "$WORKDIR/clientscripts"
    rm -f "$WORKDIR/clientscripts.tar.bz2"
  fi
}

buildfailure()
{
  touch "$OUTPUTDIR/failed"
  [ -f "$OUTPUTDIR/running" ] && rm "$OUTPUTDIR/running"

  logprint "Performing cleanup"
  clean_files

  $SCRIPTS/clean.sh >> $LOG 2>&1

  return 1
}

applypatch()
{
  local PATCH=$1
  local PACKAGE=$2

  if echo $PATCH | grep "/disabled/" > /dev/null 2>&1; then
    return
  fi

  if [ ! -d "$WORKDIR/source/$PACKAGE" ]; then
    echo "$WORKDIR/source/$PACKAGE not found"
    return
  fi


  logprint "Applying $PATCH to $PACKAGE"
  cd "$WORKDIR/source/$PACKAGE"
  if grep '^+++ b/' "$PATCHDIR/$PATCH" > /dev/null 2>&1; then
    patch -p1 -i "$PATCHDIR/$PATCH" -r - >> $LOG 2>&1
  else
    patch -p0 -i "$PATCHDIR/$PATCH" -r - >> $LOG 2>&1
  fi
}

applypatches()
{
  if ! [ -d "$PATCHDIR" ]; then
    logprint "Patchdir does not exist"
    return;
  fi
  logprint "Applying patches"
  cd "$PATCHDIR"
  local PATCHES=`find . -name "*.patch" -o -name "*.diff"`
  for i in $PATCHES; do
    local PATCH=${i#./}
    local PACKAGE=${PATCH%%/*}
    applypatch $PATCH $PACKAGE
  done
}

export DATE=`date "+%Y-%m-%d"`
export SHORTDATE=`date "+%Y%m%d"`
export OUTPUTDIR="$WWWDIR/$DATE"
export LOG="$OUTPUTDIR/build.log"

rm -rf "$OUTPUTDIR"
mkdir -p "$OUTPUTDIR" || buildfailure || exit 1

ln -snf "$DATE" "$WWWDIR/latest"

if [ -d "$PATCHDIR" ]; then
  cp -rp "$PATCHDIR" "$OUTPUTDIR"
fi

touch "$OUTPUTDIR/running"
logprint "FileZilla 3 build log"
logprint "---------------------\n"
START=`date "+%Y-%m-%d %H:%M:%S"`

logprint "Build started: $START\n"
resetHosts || buildfailure || exit 1
while getHost; do
  for TARGET in $TARGETS; do
    FTARGET="${TARGET##*/}"
    mkdir -p "$OUTPUTDIR/$FTARGET"
    touch "$OUTPUTDIR/$FTARGET/pending"
  done
done
resetHosts

mkdir -p "$WORKDIR" || buildfailure || exit 1
clean_files

if [ "$UPDATE" = "true" ]; then
  updatesrc || buildfailure || exit 1
fi

logprint "Copying source"
mkdir -p "$WORKDIR/source"

resetPackages || buildfailure || exit 1
while getPackage; do
  rsync -av --delete --exclude .svn/ --exclude .git/ --exclude .cvs/ --chmod=o+r,Do+x "$SRCDIR/${PACKAGE_REPO}/" "$WORKDIR/source/${PACKAGE}" || buildfailure || exit 1
done

applypatches

logprint "Generating configure files"
resetPackages || buildfailure || exit 1
while getPackage; do
  cd "$WORKDIR/source/$PACKAGE"
  if [ -f configure.ac ] && [ ! -e configure ]; then
    echo "Running autoreconf -i for package $PACKAGE" >> $LOG
    autoreconf -i >> $LOG 2>&1 || buildfailure || exit 1
  fi
done

makedist || buildfailure || exit 1

prebuild >> $LOG 2>&1 || buildfailure || exit 1

packageClientscripts()
{
  cp -r "$CLIENTSCRIPTS" "$WORKDIR"
  cp "$SCRIPTS/util.sh" "$WORKDIR/clientscripts/"
  cp "$SCRIPTS/readpackages" "$WORKDIR/clientscripts/"
  cp "$CONFDIR/packages" "$WORKDIR/clientscripts/"

  cd "$WORKDIR"
  tar -cjf "$WORKDIR/clientscripts.tar.bz2" --exclude='.svn' clientscripts
}

logprint "Packaging clientscripts"
packageClientscripts

echo "Preparation stage complete"
echo "--------------------------"

ID=1

while getHost; do

  echo Forking buildscript $ID
  buildspawn $ID "$HOST" "$HOSTPREFIX" "$TARGETS" &

  ID=$(($ID+1))

done


echo Waiting for clients
wait

postbuild >> $LOG 2>&1

if [ "$CLEAN" = "true" ]; then
  logprint "Performing cleanup"
  clean_files

  $SCRIPTS/clean.sh >> $LOG 2>&1
else
  logprint "Skipping cleanup"
fi


touch "$OUTPUTDIR/successful"
rm "$OUTPUTDIR/running"

STOP=`date "+%Y-%m-%d %H:%M:%S"`
logprint "Completed $STOP"
