#!/bin/bash

# Copyright 2004, ..., 2017  Jean-Philippe Guillemin <jp.guillemin@free.fr>
# All rights reserved.
#
#   Permission to use, copy, modify, and distribute this software for
#   any purpose with or without fee is hereby granted, provided that
#   the above copyright notice and this permission notice appear in all
#   copies.
#
#   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
#   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#   IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.

. /etc/shell-colors

export CWD=$(pwd)

if [ "$1" = "" ]; then
	echo -e "${BOLDCYAN}This tool creates Slackware packages from source source-tarball-version.tar.?z|zip ${COLOR_RESET}"
	echo -e "${BOLDCYAN}usage $0 TARBALL ${COLOR_RESET}"
	echo -e "${BOLDCYAN}OR usage $0 NAME ${COLOR_RESET}"
	echo -e "${BOLDCYAN}optional environment variables are : \$OUTPUT \$EXTRACONFIG${COLOR_RESET}"
	exit
fi
export ME=$(which $0)

export JOBS=$(nproc)

if [ -e ${CWD}/$(basename "$1") ]; then
	SRCPKG="$(basename "$1")"
	nbfields=$(tr -dc '-' <<< "$SRCPKG" | wc -c)
	nbfields=$(($nbfields - 1))
	IFS='-' read -ra field <<< "$SRCPKG"
	NAME="${field[0]}"
	for i in $(seq 1 $nbfields); do NAME="$NAME-${field[$i]}"; done
	export $NAME
else
	export NAME="$1"	
	SRCPKG=$(ls ${NAME}*tar* 2>/dev/null || ls ${NAME}*zip 2>/dev/null || ls ${NAME}*z 2>/dev/null ||exit 1) 
	[ ! -e ${CWD}/$(basename "$SRCPKG") ] && exit 1
fi

if [ "$(ls ${NAME}*tar*)" ] ; then
	VERSION=${SRCPKG%.*};VERSION=${VERSION%.*}; export VERSION=${VERSION##*-}
else
	VERSION=${SRCPKG%.*}; export VERSION=${VERSION##*-}
fi

BUILD="$(date '+%y%m%d')"

# Automatically determine the architecture we're building on:
if [ -z "${ARCH}" ]; then
	case "$( uname -m )" in
		i?86) export ARCH=i486 ;;
		arm*) export ARCH=arm ;;
		   *) export ARCH=$( uname -m ) ;;
	esac
fi

if [ "${ARCH}" = "i486" ]; then
	SLKCFLAGS="-O2 -march=i486 -mtune=i686"
	export LIBDIRSUFFIX=""
elif [ "${ARCH}" = "i686" ]; then
	SLKCFLAGS="-O2 -march=i686 -mtune=i686"
	export LIBDIRSUFFIX=""
elif [ "${ARCH}" = "x86_64" ]; then
	SLKCFLAGS="-O2 -fPIC"
	export LIBDIRSUFFIX="64"
else
	SLKCFLAGS="-O2"
	export LIBDIRSUFFIX=""
fi

OUTPUT=${OUTPUT:-/tmp}

export PKG="${OUTPUT}/${NAME}-${VERSION}-${ARCH}-$BUILD"
rm -rf ${PKG}
rm -f ${PKG}.txz
mkdir -p ${PKG}

export EXTRACONFIG

export TMP="${CWD}/tmp"

cd ${CWD}
rm -rf ${TMP}
mkdir -p ${TMP}
echo -e "${BOLDCYAN}Extracting source ${SRCPKG} ${COLOR_RESET}"
(
cd ${TMP}
tar xvf ${CWD}/${SRCPKG} || unzip ${CWD}/${SRCPKG}
)

export SRC=$(ls -d ${TMP}/*/)
  
cd ${SRC}
chown -R root.root .
find . -perm 777 -exec chmod 755 {} \;
find . -perm 775 -exec chmod 755 {} \;
find . -perm 666 -exec chmod 644 {} \;
find . -perm 664 -exec chmod 644 {} \;

export CFLAGS="$SLKCFLAGS" 
export CXXFLAGS="$SLKCFLAGS" 
export PREFIX=/usr
export LIBINSTALLDIR=${PREFIX}/lib${LIBDIRSUFFIX} 
export ICEAUTH=${PREFIX}/bin/iceauth

# some custom pre build instructions
if [ -e ${CWD}/prebuild.sh ]; then 
echo -e "${BOLDCYAN}Executing prebuild script${COLOR_RESET}"
	. ${CWD}/prebuild.sh 
fi

echo -e "${BOLDCYAN}About to build ${NAME} ${COLOR_RESET}"
echo -e "${BOLDCYAN}Using source ${SRCPKG} ${COLOR_RESET}"
echo -e "${BOLDCYAN}output package will be ${PKG}.txz ${COLOR_RESET}"
[ "${EXTRACONFIG}" != "" ] &&  echo -e "${BOLDCYAN}Extraconfig options are : ${EXTRACONFIG} ${COLOR_RESET}"
sleep 2

# Sorry , but fed up with these :/
rm -f /usr/lib64/*.la

# unless you need to fix things..
alias make="make -s"

makebuild(){
	make -j${JOBS} prefix=${PREFIX} libdir=${LIBINSTALLDIR} mandir=${PREFIX}/man || exit 1
	make install DESTDIR=${PKG} prefix=${PREFIX} libdir=${LIBINSTALLDIR} mandir=${PREFIX}/man || exit 1
}


# First do we have custom build commands ?
if [ -e ${CWD}/configure.sh ]; then
	. ${CWD}/configure.sh 
fi

if [ -e ${CWD}/build.sh ]; then
echo -e "${BOLDCYAN}Executing custom build script ${COLOR_RESET}"
	. ${CWD}/build.sh 
	
# Else let's try to be automagic :

# MESON
elif [ -e ${SRC}/meson.build ]; then
echo -e "${BOLDCYAN}Building and installing source (MESON)${COLOR_RESET}"
		meson --prefix ${PREFIX} --libdir ${LIBINSTALLDIR} builddir || exit 1
		(
			cd builddir
			meson configure -Dprefix=${PREFIX} -Denable-wayland=false $EXTRACONFIG
			ninja
			DESTDIR=${PKG} ninja install
		)

# PYTHON
elif [ -e ${SRC}/setup.py ]; then
echo -e "${BOLDCYAN}Building and installing source (PYTHON)${COLOR_RESET}"
		python2 setup.py install --prefix=${PREFIX} --root=${PKG} $EXTRACONFIG 

# PERL
elif [ -e ${SRC}/Makefile.PL ]; then
echo -e "${BOLDCYAN}Building and installing source (PERL)${COLOR_RESET}"
		perl Makefile.PL $EXTRACONFIG || exit 1
		make
		make install DESTDIR=${PKG}
		
# CMAKE
elif [ -e ${SRC}/*.cmake -o -e ${SRC}/CMake* ]; then
echo -e "${BOLDCYAN}Building and installing source (CMAKE)${COLOR_RESET}"
		mkdir build
		(
			cd build
			cmake \
				-DCMAKE_C_FLAGS:STRING="${CFLAGS}" \
				-DCMAKE_CXX_FLAGS:STRING="${CXXFLAGS}" \
				-DCMAKE_INSTALL_PREFIX:STRING="${PREFIX}" \
				-DLIB_SUFFIX:STRING="${LIBDIRSUFFIX}" \
				-DLIB_INSTALL_DIR:STRING="${LIBINSTALLDIR}" \
				-DCMAKE_INSTALL_RPATH:STRING="${LIBINSTALLDIR}" \
				-DWITH_DOCDIR:STRING="${PREFIX}/doc/${NAME}-${VERSION}" \
				-DMAN_INSTALL_DIR:STRING="${PREFIX}/man" \
				-DSYSCONF_INSTALL_DIR:STRING="/etc" \
				-DINCLUDE_INSTALL_DIR:STRING="${PREFIX}/include" \
				-DBUILD_SHARED_LIBS:BOOL=ON \
				$EXTRACONFIG \
				-DCMAKE_BUILD_TYPE=Release .. || exit 1
			makebuild
		)

# CLASSIC CONFIGURE
else 
		if [ ! -e ${SRC}/configure ]; then
			./autogen.sh || autoreconf -fiv
		fi

		[ -e ${SRC}/configure ] && ./configure \
		  --prefix=${PREFIX} \
		  --mandir=${PREFIX}/man \
		  --docdir=${PREFIX}/doc/${NAME}-${VERSION} \
		  --libdir=${LIBINSTALLDIR} \
		  --localstatedir=/var \
		  --localedir=${PREFIX}/share/locale \
		  --sysconfdir=/etc \
		  --enable-static=no \
		  --disable-static \
		  --enable-shared \
		  --enable-final \
		  --disable-debug \
		  --disable-schemas-compile \
		  --enable-gio \
		  --with-sound=pulseaudio \
		  --enable-gtk-doc=no \
		  --enable-gtk-doc-html=no \
		  --enable-gtk3 \
		  --with-gtk=3 \
		  --enable-introspection \
		  --enable-notifications \
		  --disable-libsystemd-login \
		  --disable-vulkan \
		  --disable-wayland \
		  --build=${ARCH}-zenwalk-linux \
		  $EXTRACONFIG || exit 1
echo -e "${BOLDCYAN}Building and installing source${COLOR_RESET}"
		makebuild
fi

# In case the Makefile is buggy

if [ "${LIBDIRSUFFIX}" = "64" ]; then
	mkdir -p ${PKG}${PREFIX}/lib${LIBDIRSUFFIX}
	mv ${PKG}${PREFIX}/lib/* ${PKG}${PREFIX}/lib${LIBDIRSUFFIX} 2> /dev/null
	rmdir ${PKG}${PREFIX}/lib ${PKG}${PREFIX}/lib64 2> /dev/null
fi

# docs
echo -e "${BOLDCYAN}Installing docs in ${PKG}${PREFIX}/doc/${NAME}-${VERSION} ${COLOR_RESET}"
mkdir -p ${PKG}${PREFIX}/doc/${NAME}-${VERSION}
(
cd ${SRC}
cp -f AUTHORS* COPYING* INSTALL README* TODO NEWS ChangeLog NOTICE Copyright Changelog documentation/* ${PKG}${PREFIX}/doc/${NAME}-${VERSION} 2> /dev/null
)
(
cd ${CWD}
cp -f configure.sh prebuild.sh build.sh postbuild.sh *.patch *.diff ${PKG}${PREFIX}/doc/${NAME}-${VERSION} 2> /dev/null
cat $ME > ${PKG}${PREFIX}/doc/${NAME}-${VERSION}/${NAME}.SlackBuild
[ "${EXTRACONFIG}" != "" ] &&  echo "${EXTRACONFIG}" > ${PKG}${PREFIX}/doc/${NAME}-${VERSION}/extraconfig
)
rm -rf ${PKG}/usr/share/gtk-doc

# Striptease
( cd ${PKG}
echo -e "${BOLDCYAN}Striping binaries${COLOR_RESET}"
	find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
	find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
echo -e "${BOLDCYAN}Removing .la files from ${PKG}${LIBINSTALLDIR} ${COLOR_RESET}"	
	find . -name *.la | xargs rm -f 
echo -e "${BOLDCYAN}Installing man pages if any ${COLOR_RESET}"
	for mandir in $(find .${PREFIX}/share/man -name man* -type d) ; do
		mkdir -p .${PREFIX}/man/$(basename $mandir)
		mv $mandir/*.? .${PREFIX}/man/$(basename $mandir)
	done	  
	rm -rf .${PREFIX}/share/man
	for mandir in $(find . -name man -type d) ; do
		if [ -d $mandir ]; then
			( cd $mandir
				find . -type f -name "*.?" -exec gzip -9 {} \;
			)
		fi
	done
)

# redundant , if any
rm -rf ${PKG}${PREFIX}/share/doc


cd ${CWD}

# some custom post build instructions

if [ -e ${CWD}/postbuild.sh ]; then
echo -e "${BOLDCYAN}Executing postbuild script ${COLOR_RESET}"
	. ${CWD}/postbuild.sh 
fi

# slack-desc, doinst.sh
mkdir -p ${PKG}/install

	cat > ${PKG}/install/slack-desc << END
${NAME}: Zenwalk package for ${NAME} 
${NAME}:
${NAME}: This ${NAME} package was created for Zenwalk GNU Linux.  
${NAME}: It can be installed on any Slackware Linux system.
${NAME}: 
${NAME}: For more information, see:  http://www.zenwalk.org
${NAME}:
${NAME}:
${NAME}:
${NAME}:
${NAME}:
END

if [ -e ${CWD}/slack-desc ]; then
echo -e "${BOLDCYAN}Installing slack-desc${COLOR_RESET}"
	cat ${CWD}/slack-desc > ${PKG}/install/slack-desc
else
echo -e "${BOLDCYAN}looking up for existing slack-desc on Internet.....${COLOR_RESET}"
	for i in a ap d l n x xap xfce kde ; do 
		wget -q --spider --no-check-certificate http://slack1.zenwalk.org/slackware/slackware64-current/source/$i/$NAME/slack-desc && break
	done
	if [ "$?" = "0" ] ; then
		wget --no-check-certificate -O ${PKG}/install/slack-desc http://slack1.zenwalk.org/slackware/slackware64-current/source/$i/$NAME/slack-desc
	else
		for i in academic accessibility audio business desktop development games gis graphics libraries misc multimedia network office perl python ruby system ; do 
			wget -q --spider --no-check-certificate https://slackbuilds.org/slackbuilds/14.2/$i/$NAME/slack-desc && break
		done
		if [ "$?" = "0" ] ; then
			wget --no-check-certificate -O ${PKG}/install/slack-desc https://slackbuilds.org/slackbuilds/14.2/$i/$NAME/slack-desc
		fi
	fi
fi

echo -e "${BOLDCYAN}Installing post-install script doinst.sh${COLOR_RESET}"
if [ -e ${CWD}/doinst.sh ]; then
	cat ${CWD}/doinst.sh > ${PKG}/install/doinst.sh
else
	if [ -e ${PKG}/${PREFIX}/share/applications ]; then
	cat >> ${PKG}/install/doinst.sh << END
if [ -x ${PREFIX}/bin/update-desktop-database ]; then
  ${PREFIX}/bin/update-desktop-database -q ${PREFIX}/share/applications >/dev/null 2>&1
fi
END
	fi
	
	if [ -e ${PKG}/${PREFIX}/share/applications ]; then
	cat >> ${PKG}/install/doinst.sh << END
if [ -e usr/share/icons/hicolor/icon-theme.cache ]; then
  if [ -x ${PREFIX}/bin/gtk-update-icon-cache ]; then
    ${PREFIX}/bin/gtk-update-icon-cache ${PREFIX}/share/icons/hicolor >/dev/null 2>&1
  fi
fi
END
	fi

	if [ -e ${PKG}/${PREFIX}/share/glib-2.0/schemas ]; then
	cat >> ${PKG}/install/doinst.sh << END
chroot . ${PREFIX}/bin/glib-compile-schemas ${PREFIX}/share/glib-2.0/schemas/ > /dev/null 2>&1
chroot . ${PREFIX}/bin/gio-querymodules ${PREFIX}/lib64/gio/modules/ > /dev/null 2>&1
END
	fi

fi

echo -e "${BOLDCYAN}Creating package...${COLOR_RESET}"
cd ${PKG}
makepkg -l y -c n ${PKG}.txz
cat ${PKG}/install/slack-desc

if [ -x  /usr/bin/requiredbuilder ]; then
echo -e "${BOLDCYAN}Generating dependecy file ${PKG}.dep ${COLOR_RESET}"
	/usr/bin/requiredbuilder -z ${PKG}.txz > ${PKG}.dep
fi

# Cleanup
cd ${CWD}
rm -rf ${PKG}
rm -rf ${TMP}
