#!/bin/bash

# Copyright (C) 2011 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#
# This programme is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This programme is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

test -z $1 && { echo "usage: <nwt-git-project> {main,main/<codename>,nightly,nightly/<codename>} [<git-checkout>]"; exit -1; }

set -ex

export GIT_SERVER="code.das-netzwerkteam.de"
export DEBEMAIL=debian@das-netzwerkteam.de
export DEBFULLNAME="NWT Packages"
export GPG_KEY="4DC41CF116990FF8"
export DIST_SUPPORTED="debian ubuntu"

set_vars() {
	USE_SUDO="yes"
	PDEBUILD="pdebuild --pbuilder qemubuilder"
	TEMP_BASE="$HOME/tmp/"
	mkdir -p "$TEMP_BASE"
	chmod 2770 "$TEMP_BASE"

	# first argv is the name of the Git project
	PROJECT=$(basename $1)
	PROJECT_PATH=$1

	# grab repository component area from command line (2nd argv) or guess it
	ARGV2_COMPONENT=$(echo "$2/" | cut -d"/" -f1)
	ARGV2_CODENAME=$(echo "$2/" | cut -d"/" -f2)
	COMPONENT=${ARGV2_COMPONENT:-${COMPONENT:-nightly}}
	CODENAMES=${ARGV2_CODENAME:-${CODENAMES}}
	[ -n "$ARGV2_CODENAME" ] && FORCE_BUILD=0 || FORCE_BUILD=-1
	if [ "x$COMPONENT" = "xmain" ]; then
		CHECKOUT=${3:-build-main}
	elif [ "x$COMPONENT" = "xnightly" ]; then
		CHECKOUT=${3:-master}
		DATE="~${DATE:-$(date +%Y%m%d)}"
	else
		echo "error: no such package component area for NWT packages. Aborting..."
		exit -1
	fi
	# the DATE might be given as ,,today'' from the command line
	[ "x$DATE" = "xtoday" ] && DATE="~$(date +%Y%m%d)"

	# setting paths
	PROJECT_DIR=$HOME/build/$COMPONENT/$PROJECT
	PKGDIST="$HOME/pkg-dist/$COMPONENT/$PROJECT"

	# build for other architectures than amd64/i386
	EXTRA_ARCHS="${EXTRA_ARCHS:-}"
	EXTRA_ARCHS_ONLY="${EXTRA_ARCHS_ONLY:-}"

	# creating paths
	mkdir -p "$TEMP_BASE"
	mkdir -p $PROJECT_DIR
	mkdir -p $PKGDIST

	return 0
}

clear_pkgdist() {

	# pkgdist directory cleanup
	cat $PROJECT_DIR/BUILDS_FOR | egrep -v '(^$|^#.*$)' | while read line; do
		l_DIST=$(echo $line | cut -d":" -f1 | tr [A-Z] [a-z])
		CODENAMES=${CODENAMES:-$(echo $line | cut -d":" -f2- | tr [A-Z] [a#-z])}
		echo "$DIST_SUPPORTED" | grep $l_DIST >/dev/null && {
			for l_CODENAME in $CODENAMES; do
				if [ "x$EXTRA_ARCHS_ONLY" = "x" ]; then
					for l_ARCH in amd64 i386; do
						mkdir -p $PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH
						rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH/$PROJECT_*.changes
						rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH/$PROJECT_*.upload
						rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH/$PROJECT_*.build
						rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH/$PROJECT_*.dsc
						rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH/$PROJECT_*.tar.gz
						rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH/*.deb
					done
				fi
				for l_EXTRA_ARCH in $EXTRA_ARCHS; do 
					mkdir -p $PKGDIST/$l_DIST/$l_CODENAME/$l_EXTRA_ARCH
					rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_EXTRA_ARCH/$PROJECT_*.changes
					rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_EXTRA_ARCH/$PROJECT_*.upload
					rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_EXTRA_ARCH/$PROJECT_*.build
					rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_EXTRA_ARCH/$PROJECT_*.dsc
					rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_EXTRA_ARCH/$PROJECT_*.tar.gz
					rm -f $PKGDIST/$l_DIST/$l_CODENAME/$l_EXTRA_ARCH/*.deb
				done	
			done
		}
	done
	return 0
}

prepare_workspace() {
	# in any case remove the BUILDS_FOR file
	rm -f $PROJECT_DIR/BUILDS_FOR

	# make sure our local working copy is up to date...

	if [ -d $PROJECT_DIR/.git ]; then 
		cd $PROJECT_DIR && git reset --hard
		git checkout --force $CHECKOUT || git checkout --force -b $CHECKOUT
		git pull origin $CHECKOUT
		# and again, get the $CHECKOUT refspec in pure state
		git reset --hard
	else
		cd $(dirname $PROJECT_DIR)
		git clone git://$GIT_SERVER/$PROJECT_PATH.git
		cd $PROJECT 
		git checkout --force $CHECKOUT || git checkout --force -b $CHECKOUT;
	fi
	cd $PROJECT_DIR

	# by default we build for all current debian versions
	test -f BUILDS_FOR || cat > BUILDS_FOR <<EOF
debian: lenny squeeze wheezy sid
ubuntu: lucid precise
EOF
	return 0
}

build_packages() {
	# use pbuilder for building all variants of this package
	cat $PROJECT_DIR/BUILDS_FOR | egrep -v '(^$|^#.*$)' | while read line; do
		l_DIST=$(echo $line | cut -d":" -f1 | tr [A-Z] [a-z])
		CODENAMES=${CODENAMES:-$(echo $line | cut -d":" -f2- | tr [A-Z] [a-z])}
		echo "$DIST_SUPPORTED" | grep $l_DIST >/dev/null && {
			for l_CODENAME in $CODENAMES; do
				TEMP_DIR="$(mktemp -d --tmpdir=$TEMP_BASE)"
				mkdir -p $TEMP_DIR/$PROJECT
				chmod 2770 "$TEMP_DIR" -Rf
				git clone --local $PROJECT_DIR $TEMP_DIR/$PROJECT/ 
				cd $TEMP_DIR/$PROJECT
				git checkout $CHECKOUT || git checkout master
				GITREV=$(nwt-gitrevno)
				# we always build native packages for our repos
				test -f debian/source/format && cat debian/source/format | egrep '^3.0.*\(quilt\)$' >/dev/null && {
					echo "3.0 (native)" > debian/source/format
				}
				# translate the version name for Debian releases
				[ "x$l_CODENAME" = "xsid" ] && VERSION=unstable
				[ "x$l_CODENAME" = "xwheezy" ] && VERSION=testing
				[ "x$l_CODENAME" = "xsqueeze" ] && VERSION=stable
				[ "x$l_CODENAME" = "xlenny" ] && VERSION=oldstable
				
				# modify the section for non-main package builds
				[ "x$COMPONENT" = "xmain" ] || {
					mv debian/control debian/control.tmp
					cat debian/control.tmp | sed  "s#Section:[\ ]*\(.*\)#Section: $COMPONENT/\1#g" > debian/control
				}
				
				# modify changelog for this build
				dch --distribution $VERSION --force-distribution -l "+$l_CODENAME~$COMPONENT$DATE~$GITREV~build" "Auto-built $l_DIST $l_CODENAME package for packages.das-netzwerkteam.de repository."
				mkdir -p $PKGDIST/$l_DIST/$l_CODENAME/{amd64,i386}
				#OTHERMIRROR="deb http://packages.das-netzwerkteam.de/debian $l_CODENAME $COMPONENT"
				OTHERMIRROR=""
				[ "x$USE_SUDO" != "xyes" ] && {
					[ "x$EXTRA_ARCHS_ONLY" = "x" ] && {
						cat debian/control | egrep 'Architecture.*(all|any|amd64)' >/dev/null && {
							DIST=$l_DIST CODENAME=$l_CODENAME ARCH=amd64 $PDEBUILD --auto-debsign --debsign-k $GPG_KEY --buildresult $PKGDIST/$l_DIST/$l_CODENAME/amd64
						}
						cat debian/control | egrep 'Architecture.*(any|i386)' >/dev/null && {
							DIST=$l_DIST CODENAME=$l_CODENAME ARCH=i386  $PDEBUILD --auto-debsign --debsign-k $GPG_KEY --buildresult $PKGDIST/$l_DIST/$l_CODENAME/i386  -- --binary-arch
						}
					}
					for extra_arch in $EXTRA_ARCHS; do
						mkdir -p $PKGDIST/$l_DIST/$l_CODENAME/$extra_arch
						cat debian/control | egrep "Architecture.*(any|$extra_arch)" >/dev/null && {
							DIST=$l_DIST CODENAME=$l_CODENAME ARCH=$extra_arch $PDEBUILD --auto-debsign --debsign-k $GPG_KEY --buildresult $PKGDIST/$l_DIST/$l_CODENAME/$extra_arch -- --binary-arch
						}
					done
				}
				[ "x$USE_SUDO" = "xyes" ] && {
					[ "x$EXTRA_ARCHS_ONLY" = "x" ] && {
						cat debian/control | egrep 'Architecture.*(all|any|amd64)' >/dev/null && {
							sudo DIST=$l_DIST CODENAME=$l_CODENAME ARCH=amd64 OTHERMIRROR="$OTHERMIRROR" $PDEBUILD --auto-debsign --debsign-k $GPG_KEY --buildresult $PKGDIST/$l_DIST/$l_CODENAME/amd64
						}
						cat debian/control | egrep 'Architecture.*(any|i386)' >/dev/null && {
							sudo DIST=$l_DIST CODENAME=$l_CODENAME ARCH=i386  OTHERMIRROR="$OTHERMIRROR" $PDEBUILD --auto-debsign --debsign-k $GPG_KEY --buildresult $PKGDIST/$l_DIST/$l_CODENAME/i386  -- --binary-arch
						}
					}
					for extra_arch in $EXTRA_ARCHS; do
						mkdir -p $PKGDIST/$l_DIST/$l_CODENAME/$extra_arch
						cat debian/control | egrep "Architecture.*(any|$extra_arch)" >/dev/null && {
						    sudo DIST=$l_DIST CODENAME=$l_CODENAME ARCH=$extra_arch OTHERMIRROR="$OTHERMIRROR" $PDEBUILD --auto-debsign --debsign-k $GPG_KEY --buildresult $PKGDIST/$l_DIST/$l_CODENAME/$extra_arch -- --binary-arch
						}
					done
				}
				cd -
				rm -Rf $TEMP_DIR
			done
			echo
		}
		echo
	done
	echo
	return 0
}

upload_packages() {
	# dupload the new packages to the reprepro repository
	cd $PKGDIST
	cat $PROJECT_DIR/BUILDS_FOR | egrep -v '(^$|^#.*$)' | while read line; do
		l_DIST=$(echo $line | cut -d":" -f1 | tr [A-Z] [a-z])
		CODENAMES=${CODENAMES:-$(echo $line | cut -d":" -f2- | tr [A-Z] [a-z])}
		for l_CODENAME in $CODENAMES; do
			if [ "x$EXTRA_ARCHS_ONLY" = "x" ]; then	
				for l_ARCH in amd64 i386; do 
					cd $PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH
					ls $PROJECT_*.changes &>/dev/null && dupload --to nwt-$l_DIST-$l_CODENAME $PROJECT_*.changes
					cd -
				done
			fi
			for l_EXTRA_ARCH in $EXTRA_ARCHS; do 
				cd $PKGDIST/$l_DIST/$l_CODENAME/$l_EXTRA_ARCH
				ls $PROJECT_*.changes &>/dev/null && dupload --to nwt-$l_DIST-$l_CODENAME $PROJECT_*.changes
				cd -
			done
		done
	done
	cd -
	return 0
}

### MAIN ###
set_vars $@ && {
	if [ "x$(basename $0)" = "xnwt-build-package" ] || [ "x$(basename $0)" = "xnwt-build+upload-package" ]; then
		cd $PROJECT_DIR && nwt-pkgneedsbuild $CHECKOUT || [ "$FORCE_BUILD" -eq 0 ] && {
			clear_pkgdist
			prepare_workspace && {
				build_packages
			}
		}
	fi
	if [ "x$(basename $0)" = "xnwt-upload-package" ] || [ "x$(basename $0)" = "xnwt-build+upload-package" ]; then
		upload_packages
	fi
}
