#!/bin/sh

#desc: build script for psi+
#downloads original psi from git, downloads psi+ patches and resources from svn
#exports and makes debian-package
#(C) Nexor <nexor@ya.ru>

#depends: build_lib, debian/*


#build_lib config part:

#0=disable svn/git checking
DO_DOWNLOAD=1

#0=disable build, only export sources
DO_BUILD=1

#1 = run sudo dpkg -i * ...
INSTALL_PKG=1

#1 = copying *.deb to local repository, default - ${HOME}/workspace/repa/ubuntu/pool
COPY_REP=0

#1 = cleanup before build: directory psi-plus-<version> and files *.deb, *.changes, *.build, *.tar.gz
CLEAN=1

#name and email for debian/changelog entry
DEBFULLNAME="Stefan Zerkalica"
DEBEMAIL="zerkalica@gmail.com"

#directory for downloads and builds
WORKSPACE_DIR="${HOME}/workspace/build"

#directory of local repository for exported debs, if COPY_REP=1
DEBS_DIR="${HOME}/workspace/repa/ubuntu-psiplus/pool"

#main project name
MID="psi-plus"

BUILD_CMD="debuild -us -uc -b"
#BUILD_CMD="debuild -S -sa"
#UPLOAD_CMD="dput psi-plus"

#RELEASE="3"

#PSI+ config part:

DISABLE_WEBKIT=0

#download sources from this svn/git
#array of string, where item is git_or_svn_url name [*] submodule1 src/submodule2, etc
# * - only download and export, do not make package
TRUNKS="http://psi-dev.googlecode.com/svn/trunk psiplus *
https://delta.affinix.com/svn/trunk/psimedia psimediaplugin *
git://github.com/zerkalica/psi-plus-debian.git psi-plus-debian *
git://git.psi-im.org/psi.git psi-plus - iris src/libpsi"
#http://psi-ru.googlecode.com/svn/branches/psi-plus psi-ru *

#Remove this plugins from distribution
RM_PLUGINS="chess python testoptplugin"

#copy this data from psiplus svn to psi-plus main package
COPY_STUFF="iconsets/system/default .
certs/rootcert.xml
iconsets/system/summer-system.jisp
iconsets/moods/silk.jisp
iconsets/emoticons/kolobok.jisp
iconsets/clients/fingerprint.jisp
iconsets/activities/psiplus-activities.jisp"

#uncomment for autocheck packages
#PACKAGES="git-core subversion quilt
#fakeroot build-essential devscripts dpkg-dev debhelper fakeroot make automake autotools-dev qt4-qmake
#libqt4-dev libqca2-dev libxss-dev libaspell-dev zlib1g-dev libsm-dev
#libgstreamer-plugins-base0.10-dev liboil0.3-dev libspeexdsp-dev"

putlog() {
	local MSG="${1}"
	local LEVEL="${2}"
	[ "${LEVEL}" != "1" ] && echo "${MSG}"
	[ "${LEVEL}" != "2" ] && echo "${MSG}" >> ${LOG_FILE}
}

die() {
	putlog " !!!ERROR: ${1}"
	exit 1
}

_init_vars() {
	SRC_DIR=$(dirname "$0")
	[ "$SRC_DIR" = "." ] && SRC_DIR=$(pwd)
	[ -n "$MID" ] || MID=`sed -n 's/^\([^ ]*\).*/\1/p;q' "$SRC_DIR/debian/changelog"`
	WORK_DIR="${WORKSPACE_DIR}/$MID"
	BUILD_DIR="${WORK_DIR}/build"
	SVN_DIR="${WORK_DIR}/git"
	DATE_SHORT=$(date +"%Y%m%d")
	DATE=$(date -R)
	LOG_FILE="${WORK_DIR}/build-$MID.log.txt"
}

_mkdir() {
	mkdir -p "$1" || die "mkdir $1"
}

_init() {
	_init_vars
	if [ "$COPY_REP"="1" ] ; then
		[ -d "$DEBS_DIR" ] || _mkdir "${DEBS_DIR}"
	fi
	[ -d "$BUILD_DIR" ] || _mkdir "${BUILD_DIR}"
	[ -d "$SVN_DIR" ] || _mkdir "${SVN_DIR}"
	echo "$DATE" > "$LOG_FILE"
}

_download_git() {
	local TRUNK="$1"
	local rID="$2"
	if [ ! -d "${SVN_DIR}/${rID}" ] ; then
		cd "${SVN_DIR}"
		git clone "${TRUNK}" "${rID}" || die "git init failed"
		cd "${SVN_DIR}/${rID}"
		git submodule init || die "git submodule init failed"
	else
		cd "${SVN_DIR}/${rID}"
		git pull || die "git update failed"
	fi
	git submodule update || die "git submodule update failed"
}

_download_svn() {
	local TRUNK="$1"
	local rID="$2"
	cd "${SVN_DIR}" && svn $SVN_OPTS co "${TRUNK}" "$rID"
}

_download_auto() {
	local TRUNK
	local rID
	local BN
	echo "${TRUNKS}" | \
	while read TRUNK rID BN; do
		if echo "$TRUNK" | grep -q 'git' ; then
				putlog "git downloading $TRUNK $rID"
			_download_git "$TRUNK" "$rID"
		else
				putlog "svn downloading $TRUNK $rID"
			_download_svn "$TRUNK" "$rID"
		fi
	done
}

_download() {
	_download_auto
}

_version_git() {
	local rID="$1"
	cd "${SVN_DIR}/${rID}" && git describe --tags | sed 's/\([.0-9]*\)[-[:alpha:]]*\([0-9]*\).*/\1.\2/'
}

_revision_svn() {
	local rID="$1"
	cd "${SVN_DIR}" && svnversion "${rID}" | sed s/M//
}

_version_svn() {
	local rID="$1"
	local VERSION=`cat "$SVN_DIR/$rID/src/version.h" 2> /dev/null | sed -n 's/.*_VERSION.*\"\([0-9]*\.[0-9]*\).*/\1/p'`
	echo "${VERSION}.$(_revision_svn "$rID")"
}

_version_auto() {
	local TRUNK
	local rID
	local BN
	local mID="$1"
	echo "${TRUNKS}" | \
	while read TRUNK rID BN; do
		echo "$rID" | grep -q "$mID" || continue
		if echo "$TRUNK" | grep -q 'git' ; then
			_version_git "$rID"
		else
			_version_svn "$rID"
		fi
		break
	done
}

_version() {
	_version_auto "$1"
}

_export_git() {
	local rID="$1"
	local lOUT_DIR="$2"
	local GIT_ADDONS="$3"
	local i
	[ -d "$lOUT_DIR" ] || mkdir -p "$lOUT_DIR"
	putlog "git export: $rID to $lOUT_DIR"
	cd "${SVN_DIR}/${rID}" && git archive --format=tar master | ( cd "$lOUT_DIR" ; tar xf - )
	if [ -n "$GIT_ADDONS" ] ; then
		for i in $GIT_ADDONS ; do
			cd "${SVN_DIR}/${rID}/${i}"
			putlog "git submodule export: ${SVN_DIR}/${rID}/${i}"
			git archive --format=tar master | ( cd "${lOUT_DIR}/${i}" ; tar xf - )
		done
	fi
}

_export_svn() {
	local rID="$1"
	local lOUT_DIR="$2"
	[ -d "$lOUT_DIR" ] && rm -rf "$lOUT_DIR"
	putlog "svn export: $rID to $lOUT_DIR"
	cd "${SVN_DIR}" && svn export "$rID" "$lOUT_DIR"
}

_export_auto() {
	local TRUNK
	local rID
	local BN
	local VERSION
	local OUT_DIR
	local TAR_NAME
	local BUILD_NAME
	local i

	[ "$CLEAN" = "1" ] && _clean

	echo "${TRUNKS}" | \
	while read TRUNK rID BN SUBMODULES; do
		VERSION=""
		[ "$BN" = "-" ] && BN=
		[ -n "$BN" ] || VERSION="$(_version "$rID")"

		BUILD_NAME="$(_get_build_name "$rID" "$VERSION")"
		OUT_DIR="$BUILD_DIR/$BUILD_NAME"


		if [ "$CLEAN" = "1" -a -z "$BN" ] ; then
			for i in "$BUILD_DIR/$rID"-* ; do
				if echo "$(basename $i)" | grep -q "$rID-[0-9.]\+\$" ; then
					putlog "cleaning $i"
					rm -rf "$i"
				fi
			done
		fi

		if echo "$TRUNK" | grep -q 'git' ; then
			_export_git "$rID" "$OUT_DIR" "$SUBMODULES"
		else
			_export_svn "$rID" "$OUT_DIR" "$SUBMODULES"
		fi

		_post_export "$rID" "$OUT_DIR"

		if [ ! -n  "$BN" ] ; then

			TAR_NAME="$(_get_build_name "$rID" "$VERSION" "_")"
			putlog "making ${TAR_NAME}.orig.tar.gz from ${BUILD_DIR}/${BUILD_NAME}"
			cd "${BUILD_DIR}" && tar czf "${TAR_NAME}.orig.tar.gz" "${BUILD_NAME}"

			putlog "making package in $OUT_DIR/debian"
			_copy_pkg "$rID" "$OUT_DIR"
			_fixchangelog "${rID}" "$VERSION" "$OUT_DIR"

			putlog "running prebuild in $OUT_DIR"
			_pre_build "$rID" "$OUT_DIR"

			putlog "do debuild in $OUT_DIR = $DO_BUILD"
			[ "$DO_BUILD" = "1" ] && _build_pkg "$rID" "$OUT_DIR"
		fi

	done
}

_export() {
	_export_auto
}

_clean() {
	local i
	putlog "cleaning in $BUILD_DIR"
	cd "$BUILD_DIR" || die "cd $BUILD_DIR"
	for i in *.diff *.patch *.deb *.changes *.build *.tar.gz ; do
		rm -f "$i"
	done
}

_copy_pkg() {
	local rID="$1"
	local OUT_DIR="$2"
	cp -Rap "$SRC_DIR/debian" "$OUT_DIR"
}

_get_build_name() {
	local rID="$1"
	local VERSION="$2"
	local SEP="$3"
	local lSEP=""
	[ -n "$SEP" ] || SEP="-"
	[ -n "$VERSION" ] && lSEP="$SEP"
	echo "${rID}${lSEP}${VERSION}"
}

_fixchangelog() {
	local rID="$1"
	local VERSION="$2"
	local OUT_DIR="$3"
	BUILDDEB_DIR="$OUT_DIR/debian"
	distname="unstable"
	if which lsb_release ; then
		distname=$(lsb_release -cs)
	fi

	[ -z "$RELEASE" ] && RELEASE="1"

	mv "${BUILDDEB_DIR}/changelog" "${BUILDDEB_DIR}/changelog.old"
	cat > "${BUILDDEB_DIR}/changelog" << EOF
${rID} (${VERSION}-${RELEASE}) ${distname}; urgency=low

  * New upstream release

 -- ${DEBFULLNAME} <${DEBEMAIL}>  ${DATE}

EOF
	cat "${BUILDDEB_DIR}/changelog.old" >> "${BUILDDEB_DIR}/changelog"
	rm "${BUILDDEB_DIR}/changelog.old"
}

_build_cmd() {
	$BUILD_CMD
}

_build_pkg() {
	local rID="$1"
	local OUT_DIR="$2"
	cd "$OUT_DIR"
	if _build_cmd ; then
		if [ "$COPY_REP" = "1" ] ; then
			rm -f "$DEBS_DIR"/${rID}_*
			rm -f "$DEBS_DIR"/${rID}-*
		fi
	fi
}

_build_end() {
		if [ "$INSTALL_PKG" = "1" ] ; then
			sudo dpkg -i "${BUILD_DIR}"/*.deb
		fi
		if [ "$COPY_REP" = "1" ] ; then
			mv "${BUILD_DIR}"/*.deb "$DEBS_DIR"
		fi
}

_pre_build() {
	echo "."
}

_post_export() {
	echo "."
}

_build_all() {
	_init
	[ -n "$PACKAGES" ] && sudo apt-get install $PACKAGES
	[ "$DO_DOWNLOAD" = "1" ] && _download
	_export

	if [ -n "$UPLOAD_CMD" ] ; then
		for i in "${BUILD_DIR}"/*_source.changes ; do
			$UPLOAD_CMD "$i"
		done
	fi

	[ "$DO_BUILD" = "1" ] && _build_end
}
#build_lib merge end

patch_psi()	{
	local OUT_DIR="$1"
	local REVISION="$2"
	local p
	putlog "patching"

	ls ${BUILD_DIR}/psiplus/patches/*.diff | sort | sed 's/.*\/\([^/]*\.diff\)/\1/g' > ${BUILD_DIR}/psiplus/patches/series

	mv ${BUILD_DIR}/psiplus/patches ${OUT_DIR}/
	cd "${OUT_DIR}"
	quilt push -af ||  die "quilt: patch not apply"
	
	rm -rf "${OUT_DIR}/patches"
	rm -rf "${OUT_DIR}"/.pc

	sed 's/<disabled\/>/<required\/>/g' -i "${OUT_DIR}/psi.qc"
	sed '/.*universal.*/,/<\/dep>/ s/<required\/>/<disabled\/>/' -i "${OUT_DIR}/psi.qc"
	if [ "$DISABLE_WEBKIT" = "1" ] ; then
		putlog "disable webkit"
		sed '/.*webkit.*/,/<\/dep>/ s/<required\/>/<disabled\/>/' -i "${OUT_DIR}/psi.qc"
		WK_STR=""
	else
		WK_STR="-webkit"
	fi
	sed "s/\(.*define PROG_VERSION .*\)xxx/\1${REVISION}${WK_STR}/" -i "${OUT_DIR}/src/applicationinfo.cpp"
}


copy_plugins() {
	local OUT_DIR="$1"
	mv -f "$BUILD_DIR/psiplus/plugins/generic"/* "$OUT_DIR/src/plugins/generic"
	[ -d "$BUILD_DIR/psimediaplugin" ] && mv -f "$BUILD_DIR/psimediaplugin" "$OUT_DIR/src/plugins/generic"
	for i in $RM_PLUGINS ; do
		rm -rf "$OUT_DIR/src/plugins/generic/$i"
	done
}

copy_resources() {
	local OUT_DIR="$1"
	local din
	local fdout
	local dout
	local i
	local shared

	#TODO: fix lintian warnings, remove later
	find "$BUILD_DIR/psiplus" -type f -exec chmod 0644 {} \;

	echo "$COPY_STUFF" | \
	while read i shared; do
		din="$BUILD_DIR/psiplus/$i"
		[ -z "$shared" ] && shared="share"
		fdout="$OUT_DIR/${shared}/${i}"
		dout="$(dirname "$fdout")"
		mkdir -p "$dout"
		cp -rf "$BUILD_DIR/psiplus"/$i "${dout}"
	done

	mkdir -p "$OUT_DIR/lang"
	mv -f "$BUILD_DIR/psiplus/lang/ru/psi_ru.qm" "$OUT_DIR/lang"
	mv -f "$BUILD_DIR/psiplus/skins" "$OUT_DIR"

	cd "$BUILD_DIR/psiplus/iconsets"
	find . -type f -name "*.jisp" | sed 's/^\.\///g' | \
	while read i ; do
		putlog "copy psi-plus icons: $i"
		echo "$COPY_STUFF" | grep -q "$i" && continue
		fdout="$OUT_DIR/iconsets-psi-plus/$i"
		mkdir -p "$(dirname "$fdout")"
		cp "$i" "$fdout"
	done
}

#hook: version
_version() {
	local VERSION=`cat "${SVN_DIR}/psi-plus/src/applicationinfo.cpp" | sed -n 's/^\#define PROG_VERSION\s*\"\([[:digit:].]*\).*/\1/p'`
	echo "${VERSION}.$(_revision_svn "psiplus")"
}

#hook: post_export
_post_export() {
	local rID="$1"
	local OUT_DIR="$2"
	if [ "$rID" = "psi-plus" ] ; then
		patch_psi "$OUT_DIR" "$(_revision_svn "psiplus")"
		copy_plugins "$OUT_DIR"
		copy_resources "$OUT_DIR"
	fi
}

#hook: copy_pkg
_copy_pkg() {
	local rID="$1"
	local OUT_DIR="$2"
  mv $BUILD_DIR/psi-plus-debian/debian $OUT_DIR/
	chmod +x "$OUT_DIR/debian/rules"
}

_build_all
