#!/bin/bash

TMPDIR=/tmp
SLACK_VER=$(cat /etc/slackware-version | sed "s/slackware *//i")

. PACKAGER

SLACKBUILD_NAME=$(basename "$0")

unset CDPATH
PATH="/usr/sbin:/sbin:/usr/bin:/bin:/usr/games:/usr/lib/java/bin:/usr/lib/java/jre/bin:/usr/lib/qt/bin:/usr/share/texmf/bin"
case $SLACK_VER in
	11.* | 10.*) PATH="/opt/kde/bin:$PATH";;
	*);;
esac

CWD=$(pwd)
PREFIX=/usr

# Hardcoded!! See COMPRESS_MAN_INFO
CONF_OPT_BASE="--sysconfdir=/etc --localstatedir=/var --mandir=/usr/man --infodir=/usr/info "

umask 022

RM () {
	echo 'RM ()'
	if [ "$PKGDIR" == '' ]; then
		echo '*** ALERT ***  !! ATTEMPT TO REMOVE FILE IN ROOT !!'
		exit 1
	fi
	for i in "$@"; do
		rm -r "$PKGDIR"/$i
	done
}

CLEAN () {
	echo 'CLEAN ()'
	rm -rf "$SRCDIR"
	rm -rf "$PKGDIR"
}

MAKE_ARCH () {
	PARCH=${PARCH:-i486}
	case $PARCH in
		i486) MARCH=$PARCH;    MCPU=i686;      ARCH=i486;;
		i?86) MARCH=$PARCH;    MCPU=$MARCH;    ARCH=$PARCH;;
		k7)   MARCH=athlon-xp; MCPU=athlon-xp; ARCH=i686;;
		p4)   MARCH=pentium4;  MCPU=pentium4;  ARCH=i686;;
		p3)   MARCH=pentium3;  MCPU=i686;      ARCH=i686;;
		p2)   MARCH=pentium2;  MCPU=pentium2;  ARCH=i686;;
		*)    MARCH=i486;      MCPU=i686;      ARCH=i486;;
	esac
	OPT=2

	case $SLACK_VER in
		10.*) CFLAGS="-march=$MARCH -mcpu=$MCPU -O$OPT";;
		*) CFLAGS="-march=$MARCH -mtune=$MCPU -O$OPT";;
	esac

	CPPFLAGS="$CFLAGS"
	CXXFLAGS="$CPPFLAGS"
	HOST=$ARCH-slackware-linux

	export CFLAGS CPPFLAGS CXXFLAGS
	export OPT MARCH MCPU PREFIX ARCH HOST
}

INITPKG () {
	MAKE_ARCH
	mkdir -p "$TMPDIR"
	NAME=$1
	VERSION=${2}
	BUILD=${3:-'1'}$SIGN
	PNAME=${PNAME:-$NAME}
	PKGNAME=$(echo $PNAME | tr [:upper:] [:lower:])-${VERSION}-$PARCH-$BUILD
	PKGDIR=$TMPDIR/$PKGNAME
	SRCDIR=${SRCDIR:-$TMPDIR/$NAME-$VERSION}
	SLACK_PATCH=$SRCDIR/slack.patch
	SBDIR="$PKGDIR/usr/src/slackbuilds/$PKGNAME"
	DOINST_IN=$SRCDIR/$PKGNAME.doinst.in
	README_PKG=$SRCDIR/README.slack
	export NAME VERSION BUILD
	rm -f  $SLACK_PATCH
	rm -rf $PKGDIR || exit 1
	rm -f  $DOINST_IN
	rm -f  $README_PKG
	mkdir -p "${PKGDIR}/install" || exit 1
	mkdir -p "${SRCDIR}" || exit 1
	cat << EOF > "$README_PKG"
Package:    $PKGNAME
Packager:   $PACKAGER <$EMAIL>
Slackware:  $SLACK_VER
Build date: $(LANG=C date)

EOF
}

EXTRACT () {
	tarball=$(find -name "$NAME-$VERSION".tar.\* | head -n 1)
	f=${1:-$tarball}
	cd $TMPDIR || exit 1
	shift
	tar -x -v "$@" -f "$CWD/$f" || exit 1
	cd "$SRCDIR" || exit 1
}

EXTRACT_ADD () {
	f=${1}
	shift
	tar -x -v -C "$SRCDIR" "$@" --strip-component=1 -f "$CWD/$f" || exit 1
	cd "$SRCDIR" || exit 1
}

PATCH () {
	PATCH=$1; shift
	echo "PATCH (): $PATCH"
	strip='-p0'
	for op in "$@"; do
		case $op in
		-p*) strip=''; break ;;
		esac
	done

	case $PATCH in
	*.bz2) bunzip2 -c "$CWD/$PATCH" | patch "$@" $strip || exit 1;;
	*.gz) gunzip -c "$CWD/$PATCH" | patch "$@" $strip || exit 1;;
	*) patch "$@" $strip < "$CWD/$PATCH" || exit 1;;
	esac
}

SLACKPATCH () {
	if [ -f $CWD/$NAME.slack.patch ]; then
		cat $CWD/$NAME.slack.patch > $SLACK_PATCH
	elif [ -f $CWD/$NAME.slack.patch.bz2 ]; then
		bzcat $CWD/$NAME.slack.patch.bz2 > $SLACK_PATCH
	elif [ -f $CWD/slack.patch.$NAME ]; then
		cat $CWD/slack.patch.$NAME > $SLACK_PATCH
	elif [ -f $CWD/slack.patch.$NAME.bz2 ]; then
		bzcat $CWD/slack.patch.$NAME.bz2 > $SLACK_PATCH
	elif [ -f $CWD/slack.patch ]; then
		cat $CWD/slack.patch > $SLACK_PATCH
	elif [ -f $CWD/slack.patch.bz2 ]; then
		bzcat $CWD/slack.patch.bz2 > $SLACK_PATCH
	fi
	if [ -f $SLACK_PATCH ]; then
		patch -p1 < $SLACK_PATCH
		echo 'The sources were patched for Slackware (see slack.patch.bz2)' >> $README_PKG
	fi

}

CONF () {
	echo 'CONF ()'

	if [ -x ./configure ]; then
		gnuCONF_OPT=${gnuCONF_OPT:-"--prefix=$PREFIX --build=$HOST $CONF_OPT_BASE"}
		myCONF_OPT="$gnuCONF_OPT $CONF_OPT"
		./configure $myCONF_OPT "$@" || exit 1
	else
		echo 'Cannot run ./configure'; exit 1
	fi
}

CMAKE () {
	echo 'CMAKE ()'

	if [ -r CMakeLists.txt ]; then
		mkdir -p ./build || exit 1
		cd ./build
		cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" "$@" .. || exit 1
	else
		echo 'File CMakeLists.txt not found'; exit 1
	fi
}

MAKE () {
	if [ "$PARCH" != 'noarch' ] && [ -z "$optinfo" ]; then
		cat << EOF >> $README_PKG

Optimizations: $CFLAGS

EOF
	optinfo='done'
	fi
# 	[ "$*" != '' ] && echo -e "\nmake with $@" >> $README_PKG
	make "$@" || exit 1
}

MAKE_INSTALL () {
	DESTDIR="$PKGDIR"
	export DESTDIR

	make install DESTDIR="${PKGDIR}" || exit 1

	if [ -d "${PKGDIR}/etc/gconf/schemas" ]; then
		echo -e "if [ -x /usr/bin/gconftool-2 ]; then" >> $DOINST_IN
		echo -e "\techo \"Installing the scheme files...\"" >> $DOINST_IN
		echo -e "\texport GCONF_CONFIG_SOURCE=\`gconftool-2 --get-default-source\`" >> $DOINST_IN
		for f in `(cd $PKGDIR/etc/gconf/schemas && ls *.schemas)`; do
			echo -e "\t/usr/bin/gconftool-2 --makefile-install-rule etc/gconf/schemas/$f 1>/dev/null" >> $DOINST_IN
		done
		echo 'fi' >> $DOINST_IN
	fi
	MAKEDOCDIR
	SHAREDIR=$(find $PKGDIR -regex ".*$PREFIX/share/.*$NAME.*" -type d | head -n 1)
}


MAKEDOCDIR () {
	MKDOCDIR
}

MKDOCDIR () {
	echo 'MKDOCDIR ()'

	[ "$DOCDIR" != '' ] && return
	if [ "$PREFIX" != '/opt/kde' ]; then
		DOCDIR=`find $PKGDIR -iregex ".*$PREFIX/doc/.*$NAME.*" -type d | head -n 1`
		if [ "$DOCDIR" == '' ]; then
			DOCDIR=$(find $PKGDIR -iregex ".*$PREFIX/share/doc/.*$NAME.*" -type d | head -n 1)
		fi
	fi
	if [ "$DOCDIR" == '' ]; then
		DOCDIR=$PKGDIR/usr/doc/$PNAME-$VERSION
		mkdir -p $DOCDIR
	fi
	echo "DOCDIR=$DOCDIR"
	export DOCDIR
# 	doc_dir=$(echo "$DOCDIR" | sed "s+$PKGDIR++")
# 	echo "doc_dir=$doc_dir"
}

ADDEXTRADOCS () {
	MAKEDOCDIR
	echo 'ADDEXTRADOCS ()'

pushd $SRCDIR || exit 1
if [ "$1" != '' ]; then
	for d in "$@"; do
		echo "ADDEXTRADOCS (): '$d'"
		cp -r "$d" "$DOCDIR/" || exit 1
	done
fi
popd || exit 1
}

ADDDOCS () {
	MAKEDOCDIR
	echo 'ADDDOCS ()'

(cd $SRCDIR || exit 1
	if [ "$NODOCS" != 'yes' ]; then
		for f in  \
		CHANGES* changes* AUTHORS* THANKS* CREDITS* \
		COPYING* FAQ* COPYRIGHT* README* NEW* ABOUT* \
		INSTALL* TODO* ChangeLog* CHANGELOG* BUG* MANUAL* LICENSE* \
		$DOCS # for compatibility
		do
			[ -f "$f" ] && cp "$f" "$DOCDIR/"
		done
	fi
)

	if [ -f $CWD/pkg.readme.$PNAME ]; then
		cat $CWD/pkg.readme.$PNAME >> $README_PKG
	elif [ -f $CWD/$PNAME.pkg.readme ]; then
		cat $CWD/$PNAME.pkg.readme >> $README_PKG
	elif [ -f $CWD/pkg.readme ]; then
		cat $CWD/pkg.readme >> $README_PKG
	fi

	cp $README_PKG $DOCDIR/
	find $DOCDIR -type f -name "*" -size -3c -exec rm -f {} \;
	# Don't use $PREFIX !
	if [ "$DOCDIR" != "$PKGDIR/usr/doc/$PNAME-${VERSION}" ]; then
		mkdir -p "$PKGDIR/usr/doc"
		mv "$DOCDIR" "$PKGDIR/usr/doc/$PNAME-${VERSION}"
		rmdir $(dirname $DOCDIR)
	fi
}

SHARE () {
	echo 'SHARE ()'

	if [ "$SHAREDIR" == '' ]; then SHAREDIR="$PKGDIR/$PREFIX/share/$NAME-${VERSION}"; fi
	echo "Share dir: $SHAREDIR"
	mkdir -p "$SHAREDIR"
	if [ "$1" != '' ]; then
		for d in "$@"; do
			cp -r "$d" "$SHAREDIR"/ || exit 1
		done
	fi
}

SLACK_DESC () {
	echo 'SLACK_DESC ()'

	for slackdesc in \
		$SLACKDESC $PNAME.slack-desc slack-desc.$PNAME slack-desc.$PNAME \
		slack-desc $PNAME.slack-desc.bz2 slack-desc.$PNAME.bz2 slack-desc.bz2; do
		if [ -f $CWD/$slackdesc ]; then
			case $slackdesc in
			*.bz2) bunzip2 -c $CWD/$slackdesc > $PKGDIR/install/slack-desc || exit 1; return;;
			*.gz) gunzip -c $CWD/$slackdesc > $PKGDIR/install/slack-desc || exit 1; return;;
			*) cat $CWD/$slackdesc > $PKGDIR/install/slack-desc || exit 1; return;;
		esac
		fi
	done
	echo 'SLACK_DESC: No slack-desc: abort'; exit 1
}

DESKTOP () {
	echo 'DESKTOP ()'

	mkdir -p $PKGDIR/usr/share
	if [ -d $CWD/desktop ]; then
		cp -r $CWD/desktop/* $PKGDIR/usr/share/
	elif [ -f $CWD/desktop.tar.bz2 ]; then
		( cd $PKGDIR/usr/share && tar xvjf $CWD/desktop.tar.bz2 )
	else echo "DESKTOP: No desktop? Don't call me then!"; exit 1
	fi
}

COMPRESS_MAN_INFO () {
	echo 'COMPRESS_MAN_INFO ()'

	if [ -d $PKGDIR/$PREFIX/share/man ]; then # FIXME The same maybe for $PKGDIR/usr/share/man
		mv $PKGDIR/$PREFIX/share/man $PKGDIR/usr/man
		rmdir -p $PKGDIR/$PREFIX/share
	fi
	find "$PKGDIR/usr/man/" -type f -exec gzip -9 {} \;
	find $PKGDIR/usr/X11*/man/ -type f -exec gzip -9 {} \;

	for d in $(find $PKGDIR/usr/man/ -type d -name "man?"); do
	( cd $d
		for l in `find -type l -maxdepth 1`; do
			s=$(stat -t -c '%N' $l | egrep -o -- "-> *\`.*'$" | egrep -o "\`.*'" | tr -d "\`'")
			rm -f $l
			echo $s | egrep ".*\.gz$" &>/dev/null || ln -sf $s.gz $l.gz
		done
	)
	done

	if [ -d $PKGDIR/usr/info ]; then
		find "$PKGDIR/usr/info/" -name "dir" -exec rm -f {} \;
		find "$PKGDIR/usr/info/" -type f -exec gzip -9 {} \;

		if ! ls -1 $PKGDIR/usr/info | egrep -v -- "-[0-9]+\.gz" > /dev/null; then
			rm -rf $PKGDIR/usr/info
			return
		fi

		echo -e "if [ -x /usr/bin/install-info ]; then" >> $DOINST_IN
		echo -e "\techo \"Installing INFO pages...\"" >> $DOINST_IN
		for i in `(cd $PKGDIR/usr/info && ls -1 | egrep -v -- "-[0-9]+\.gz")`; do
			echo -e "\t/usr/bin/install-info --info-dir=/usr/info /usr/info/$i 1>/dev/null 2>/dev/null" >> $DOINST_IN
		done
		echo "fi" >> $DOINST_IN
	fi
}

PERM () {
	echo 'PERM ()'

	case $SLACK_VER in
		10.*) bin_owner='root.bin';;
		*) bin_owner='root.root';;
	esac

	for d in usr opt var etc; do
		chown -R root.root $PKGDIR/$d 2>/dev/null
		chmod -R a=rX $PKGDIR/$d 2>/dev/null
		chmod -R u+w $PKGDIR/$d 2>/dev/null
	done

	for d in man info; do
		[ -d "$PKGDIR/usr/$d" ] && find "$PKGDIR/usr/$d" -type f -exec chmod a-x {} \;
	done

	for d in bin sbin usr/bin usr/sbin usr/X11R6/sbin usr/X11R6/bin; do
		chown -R $bin_owner $PKGDIR/$d 2>/dev/null
		chmod -R 755 $PKGDIR/$d 2>/dev/null
	done

	for d in usr/share opt/share; do
		# What if spaces are in files' names?
		[ -d "$PKGDIR/usr/$d" ] && \
		find $PKGDIR/$d -type f -print0 | xargs -0 file | grep -v 'script text' | cut -f 1 -d : | xargs chmod a-x

		chmod -R a+rX $PKGDIR/$d 2>/dev/null
		chmod -R u+w $PKGDIR/$d 2>/dev/null
	done

	EXTRA_PERM
}

STRIP () {
	echo 'STRIP ()'
	if find "$PKGDIR" -type f -exec file {} \; | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2>/dev/null; then
		if [ "$PARCH" == 'noarch' ]; then
			echo "** ERROR: ELF found, but \$PARCH='noarch'"; exit 1
		fi
	else
		if [ "$PARCH" != 'noarch' ]; then
			echo "** ERROR: ELF not found, but \$PARCH=$PARCH (must be 'noarch')"; exit 1
		fi
	fi
}

DOINST_SH () {
	echo 'DOINST_IN_SH ()'
	if [ "$1" != '' ]; then
#		for f in "$@" "${CWD}/doinst.sh.in"; do
		for f in "$@"; do
			case $f in
			*.bz2) bunzip2 -c $f >> $DOINST_IN || exit 1;;
			*.gz) gunzip -c $f >> $DOINST_IN || exit 1;;
			*) cat $f >> $DOINST_IN || exit 1;;
			esac
		done
	fi
}

SLACKBUILD () {
	echo 'SLACKBUILD ()'
	mkdir -p "${SBDIR}"
	cat "${CWD}/${SLACKBUILD_NAME}" | sed "s^\. *\.\./\(.*\)\.inc^. \1.inc^" > "${SBDIR}/SlackBuild"
	cat "${CWD}/../SlackBuild.inc" | sed "s^\. *\.\./PACKAGER^. PACKAGER^" > "${SBDIR}/SlackBuild.inc"
	cat "${CWD}/../PACKAGER" > "${SBDIR}/PACKAGER"
	[ -r "${CWD}/perl_build.inc" ] && cat "${CWD}/perl_build.inc" | sed "s^\. *\.\./\(.*\)\.inc^. \1.inc^" > "${SBDIR}/perl_build.inc"
	if [ -f "${SLACK_PATCH}" ]; then
		bzip2 -9 -f "${SLACK_PATCH}"
		cp "${SLACK_PATCH}.bz2" ${SBDIR}/
	fi
}

MAKEPKG () {
# This order!
	echo 'MAKEPKG ()'
	find $PKGDIR -name ".directory" -exec rm {} \;
	find $PKGDIR -name "*~" -exec rm {} \;
	find $PKGDIR -iname "*.old" -exec rm {} \;
	find $PKGDIR -iname "*.bak" -exec rm {} \;
	find $PKGDIR -name ".svn" -exec rm -rf {} \;
	find $PKGDIR -name "perllocal.pod" -exec rm {} \; # We don't need perllocal.pod with packaging system
	SLACK_DESC
	STRIP
	COMPRESS_MAN_INFO
	ADDDOCS
	SLACKBUILD
	if [ -f $DOINST_IN ]; then
		cp -f $DOINST_IN $PKGDIR/install/doinst.sh || exit 1
	fi
	PERM
	cd $PKGDIR
	if ! [ -f ./install/slack-desc ]; then
		echo "MAKEPKG: No slack-desc: abort"
		exit 1
	fi

#	find $PKGDIR -type f -maxdepth 1 -exec rm -f {} \; && echo "** WARNING **  Files in root! Removed!"

	makepkg -l y -c n -p ../$PKGNAME.tgz
	(cd .. && md5sum $PKGNAME.tgz > $PKGNAME.tgz.md5)
	echo "Package $TMPDIR/$PKGNAME.tgz"
	mkdir -p $PACKAGES/$PARCH
	if [ ! -f $PACKAGES/$PARCH/$PKGNAME.tgz ]; then
		cp ../$PKGNAME.tgz ../$PKGNAME.tgz.md5 $PACKAGES/$PARCH/ || exit 1
	else
		echo "Already exists: $PACKAGES/$PARCH/$PKGNAME.tgz"; exit 1
	fi
	chown -R $PKGOWNER $PACKAGES
	echo "Copied to $PACKAGES/$PARCH/$PKGNAME.tgz"
	[ "$SLACK_CLEAN" == 'yes' ] && CLEAN
	cd "$CWD"

	unset PNAME
	unset DOCS
	unset gnuCONF_OPT
	unset DOCDIR
	unset SHAREDIR
}
