#! /bin/bash

VAR_DIR_NAME=var
REPO_DIR_NAME=trunk
CONFIGURATION=TestRelease

if [ -z "$SVN" ]
then
	SVN=`which svn`
fi

VAR=../$VAR_DIR_NAME/
LOG=$VAR/log/
LOG_OLD=$VAR/log-old/
LOG_SUCCESS=$VAR/log-success/
COCOA_SRC_DIR=src/Cocoa/
SNAPSHOT_MACRO_FILE=$COCOA_SRC_DIR/oolite-snapshot.xcconfig
BUILD_DIR=build/$CONFIGURATION/

LAST_REVISION_FILE=$VAR/revision
SUCCESS_REVISION_FILE=$VAR/success_revision
PREVIOUS_SUCCESS_REVISION_FILE=$VAR/previous_success_revision
LATEST_NAME_FILE=$VAR/latest
CHANGELOG_FILE=$LOG/change_log
DIAGNOSTICS_FILE=$LOG/diagnostics
STDERR_FILE=$LOG/xcb_stderr.txt
STDOUT_FILE=$LOG/xcb_stdout.txt
STATUS_FILE=$LOG/build_log
SVNUP_FILE=$LOG/svnup.txt
LAST_UPDATED_FILE="$VAR/last_updated"

OOLITE_APP_PKG=$BUILD_DIR/Oolite.app
DEBUG_OXP_PKG=$BUILD_DIR/Debug.oxp

FTP_URL_FILE=../config/ftp_url
FTP_CREDENTIALS_FILE=../config/ftp_credentials
FTP_INFO_SET=0


function report
{
	if [ `which growlnotify` ]
	then
		growlnotify -n "Oolite nightly build" -s "$1" -m "$2"
	fi
	echo $2
}


function fail
{
	if [ $FTP_INFO_SET -eq 1 ] && [ -e $LAST_REVISION_FILE ]
	then
		curl --silent $FTP_CREDENTIALS -T "$LAST_REVISION_FILE" "$FTP_URL/revision"
	fi
	report "Oolite nightly build failure" "$1"
	exit 1
}


if [ ! -e $REPO_DIR_NAME ]
then
	# Check out repo if necessary.
	CLEAN_CHECKOUT=1
	
	echo "Checking out Oolite..."
	$SVN checkout --quiet svn://svn.berlios.de/oolite-linux/trunk $REPO_DIR_NAME
	if [ ! $? ]
	then
		fail "Failed to check out."
	fi
	
	if [ -e $REPO_DIR_NAME/$LAST_REVISION_FILE ]
	then
		rm $REPO_DIR_NAME/$LAST_REVISION_FILE
	fi
	
	# Run update-mozilla script up front so there's a bit of feedback.
	pushd $REPO_DIR_NAME/deps/Cocoa-deps/scripts > /dev/null
	./update-mozilla.sh
	UPDATE_RESULT=$1
	popd > /dev/null
	
	if [ ! $UPDATE_RESULT ]
	then
		exit 1
	fi
else
	CLEAN_CHECKOUT=0
fi


cd $REPO_DIR_NAME


# ftp_url should contain a URL to an upload directory.
# ftp_credentials should contain command line arguments for curl authentication,
# such as -u user:password.
if [ -e $FTP_URL_FILE ] && [ -e $FTP_CREDENTIALS_FILE ]
then
	FTP_URL=`head -n 1 "$FTP_URL_FILE"`
	FTP_CREDENTIALS=`head -n 1 "$FTP_CREDENTIALS_FILE"`
	FTP_INFO_SET=1
else
	FTP_INFO_SET=0
fi

# Get $OOLITE_VERSION
source $COCOA_SRC_DIR/oolite-version.xcconfig


# Ensure output directories exist.
if [ ! -e $VAR ]
then
	mkdir $VAR
fi


if [ -e $LOG ]
then
	if [ -e $LOG_OLD ]
	then
		rm -rf $LOG_OLD
	fi
	mv $LOG $LOG_OLD
fi


mkdir $LOG


# Get last revision.
if [ ! -e $LAST_REVISION_FILE ]
then
	LAST_REVISION=0
else
	LAST_REVISION=`head -n 1 "$LAST_REVISION_FILE"`
fi


if [ $CLEAN_CHECKOUT -eq 0 ]
then
	# Revert the file we manipulate for watermarking, then update repo.
	echo "Updating..."
	$SVN revert --quiet $SNAPSHOT_MACRO_FILE
	$SVN update > $SVNUP_FILE
	if [ $? -ne 0 ]
	then
		echo "Update failed: " > $DIAGNOSTICS_FILE
		cat $SVNUP_FILE >> $DIAGNOSTICS_FILE
		fail "SVN update failed."
	fi
fi


# Get current revision.
CURRENT_REVISION=`$SVN info 2> /dev/null | grep "Revision:" | cut -f 2 -d " "`
if [ ! $? ]
then
	fail "Could not get revision number."
fi

if [ $LAST_REVISION -eq $CURRENT_REVISION ]
then
	report "Oolite nightly unchanged" "No change, still at revision $LAST_REVISION."
	exit 0
fi

echo "Updated from revision $LAST_REVISION to $CURRENT_REVISION, building..."


# Delete existing build products so no old files are left lying around.
if [ -e $OOLITE_APP_PKG ]
then
	rm -rf $OOLITE_APP_PKG
fi
if [ -e $DEBUG_OXP_PKG ]
then
	rm -rf $DEBUG_OXP_PKG
fi


# Nastytacular: overwrite the oolite-snapshot.xcconfig file to generate the nightly watermark macros.
# The backslash jungle builds a string like -DOOLITE_SNAPSHOT_VERSION="\"1.74-3040\"".
echo "SNAPSHOT_MACROS= -DSNAPSHOT_BUILD=1 -DOOLITE_SNAPSHOT_VERSION=\"\\\"$OOLITE_VERSION-$CURRENT_REVISION\\\"\"" > src/Cocoa/oolite-snapshot.xcconfig

# Buildez la vache!
xcodebuild clean build -project Oolite.xcodeproj -target "Build All" -configuration $CONFIGURATION RUN_CLANG_STATIC_ANALYZER=NO >$STDOUT_FILE 2>$STDERR_FILE

# Generate status and diagnostics files. The -mlong-branch bit filters out
# an unimportant warning generated by a bug in the 10.4 SDK for Xcode 3.2.
grep "^[^\ ]" $STDOUT_FILE > $STATUS_FILE
grep -e "warning:" -e "error:" $STDOUT_FILE | grep -v -e "-mlong-branch" > $DIAGNOSTICS_FILE


# Set last revision regardless of success or failure, on the basis that a
# failed build isn't likely to suddenly work if you just retry it a day later.
echo $CURRENT_REVISION > $LAST_REVISION_FILE


# Check for failure.
grep -e "^\*\* BUILD FAILED \*\*$" $STDERR_FILE
if [ $? -ne 1 ]
then
	ERROR_COUNT=`grep "error:" $STDOUT_FILE | wc -l | tr -d " "`
	WARNING_COUNT=`grep "warning:" $STDOUT_FILE | wc -l | tr -d " "`
	fail "Build failed with $ERROR_COUNT errors and $WARNING_COUNT warnings."
fi


# Write changelog.
if [ $LAST_REVISION -ne 0 ]
then
	$SVN log -r$CURRENT_REVISION:$[$LAST_REVISION + 1] > $CHANGELOG_FILE
else
	echo "Initial checkout." > $CHANGELOG_FILE
fi

mv $SUCCESS_REVISION_FILE $PREVIOUS_SUCCESS_REVISION_FILE
echo $CURRENT_REVISION > $SUCCESS_REVISION_FILE


# Keep logs of latest successful build.
if [ -e $LOG_SUCCESS ]
then
	rm -rf $LOG_SUCCESS
fi
cp -R $LOG $LOG_SUCCESS


# Pack up a zip file.
if ! echo "$OOLITE_VERSION" | grep "[0-9]*\.[0-9]*\.[0-9]*" > /dev/null
then
	OOLITE_VERSION="$OOLITE_VERSION.0"
fi

FULLVERSION=$OOLITE_VERSION.$CURRENT_REVISION-dev
echo "Packaging nightly $FULLVERSION..."

PACKAGE_NAME=Oolite-nightly-$FULLVERSION
PACKAGE_DIR=$VAR/$PACKAGE_NAME/
ADDONS_DIR=$PACKAGE_DIR/AddOns/
ZIP_NAME=oolite-trunk-$FULLVERSION.mac.zip
echo $ZIP_NAME > "$LATEST_NAME_FILE"

mkdir $PACKAGE_DIR
cp -R $OOLITE_APP_PKG $PACKAGE_DIR
mkdir $ADDONS_DIR
cp -R $DEBUG_OXP_PKG $ADDONS_DIR

pushd $VAR > /dev/null
ditto -ck --noqtn --noacl --nocache --zlibCompressionLevel 9 $PACKAGE_NAME $ZIP_NAME
if [ ! $? ]
then
	fail "Could not create zip archive (ditto failed with exit code $?)."
fi
rm -rf $PACKAGE_NAME
popd > /dev/null


# Record date of this momentous event.
date > $LAST_UPDATED_FILE

if [ ! -e $VAR/$ZIP_NAME ]
then
	fail "Archive was not made for some reason."
fi

if [ $FTP_INFO_SET -eq 0 ]
then
	report "Oolite nightly success" "Build succeeded, but ftp_url and/or ftp_credentials are missing, so data cannot be uploaded."
	exit 0
fi


echo "Uploading $ZIP_NAME..."
curl "-#" $FTP_CREDENTIALS -T "$VAR/$ZIP_NAME" "$FTP_URL/$ZIP_NAME"
if [ ! $? ]
then
	echo ""
	fail "Upload failed ($?)."
fi

echo ""
echo "Uploading metadata..."
curl --silent $FTP_CREDENTIALS -T "$LAST_UPDATED_FILE" "$FTP_URL/last_updated"
curl --silent $FTP_CREDENTIALS -T "$CHANGELOG_FILE" "$FTP_URL/change_log"
curl --silent $FTP_CREDENTIALS -T "$DIAGNOSTICS_FILE" "$FTP_URL/diagnostics"
curl --silent $FTP_CREDENTIALS -T "$STATUS_FILE" "$FTP_URL/build_log"
curl --silent $FTP_CREDENTIALS -T "$LAST_REVISION_FILE" "$FTP_URL/revision"
curl --silent $FTP_CREDENTIALS -T "$PREVIOUS_SUCCESS_REVISION_FILE" "$FTP_URL/previous_successful"
curl --silent $FTP_CREDENTIALS -T "$LATEST_NAME_FILE" "$FTP_URL/latest"


rm $VAR/$ZIP_NAME
report $"Oolite nightly success" "Successfully built r$CURRENT_REVISION and uploaded as $ZIP_NAME."
