#!/bin/bash

# Copyright 2004, ..., 2017  Jean-Philippe Guillemin <h1p8r10n@yandex.com>
# All rights reserved.
#
#   Permission to use, copy, modify, and distribute this patch 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}This tool creates Slackware packages from binary DEB or RPM packages ${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 export NAME="$NAME-${field[$i]}"; done
else
	export NAME="$1"	
	SRCPKG=$(ls ${NAME}*tar* 2>/dev/null || ls ${NAME}*zip 2>/dev/null || ls ${NAME}*z 2>/dev/null || ls ${NAME}*rpm 2>/dev/null || ls ${NAME}*deb 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}

case ${SRCPKG##*.} in
gz)
  tar zxvf ${CWD}/${SRCPKG} || exit 1
  ;;
xz)
  tar Jxvf ${CWD}/${SRCPKG} || exit 1
  ;;
bz2)
  tar jxvf ${CWD}/${SRCPKG} || exit 1
  ;;
zip)
  unzip ${CWD}/${SRCPKG}
  ;;
rpm)
  mkdir srcpkg
  cd srcpkg
  rpm2cpio ${CWD}/${SRCPKG} > ${CWD}/${SRCPKG}.cpio 2> /dev/null
  ( cd ${PKG} ; cpio -i -m -d < ${CWD}/${SRCPKG}.cpio 1> /dev/null 2> /dev/null )
  rm -f ${CWD}/${SRCPKG}.cpio
  touch ${CWD}/build.sh
  ;;
deb) 
  cd ${PKG}  
  ar x ${CWD}/${SRCPKG}
  tar -xvf data.tar.*z
  rm -rf data*
  rm -rf control* 
  rm -rf debian*
  touch ${CWD}/build.sh
  ;;  
txz) 
  cd ${PKG}  
  tar xvf ${CWD}/${SRCPKG}
  bash install/doinst.sh
  touch ${CWD}/build.sh
  ;;  
*)
  tar xvf ${CWD}/${SRCPKG} || exit 1
  ;;
esac

)

export SRC=$(ls -d ${TMP}/*/)
cd ${SRC} 
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

# 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 PREFIX=${PREFIX} LIBDIR=${LIBINSTALLDIR} check || \
	make -j${JOBS} prefix=${PREFIX} libdir=${LIBINSTALLDIR} mandir=${PREFIX}/man PREFIX=${PREFIX} LIBDIR=${LIBINSTALLDIR} || exit 1
	make install DESTDIR=${PKG} prefix=${PREFIX} libdir=${LIBINSTALLDIR} mandir=${PREFIX}/man PREFIX=${PREFIX} LIBDIR=${LIBINSTALLDIR} || exit 1
}

export CONFIG="\
--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 \
"

echo -e "${BOLDCYAN}Aplying patches ${COLOR_RESET}"

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}"

if [ -e ${CWD}/build.sh ]; then
echo -e "${BOLDCYAN}Executing custom build script ${COLOR_RESET}"
sleep 2
	. ${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}"
export CONFIG="\
-Dprefix=${PREFIX} \
-Dmandir=${PREFIX}/man \
-Ddocdir=${PREFIX}/doc/${NAME}-${VERSION} \
-Dlibdir=${LIBINSTALLDIR} \
-Dlocalstatedir=/var \
-Dlocaledir=${PREFIX}/share/locale \
-Dsysconfdir=/etc \
-Denable-static=no \
-Ddisable-static=yes \
-Denable-shared=yes \
-Denable-final=yes \
-Ddisable-debug=yes \
-Ddisable-schemas-compile=yes \
-Denable-gio=yes \
-Dwith-sound=pulseaudio \
-Denable-gtk-doc=no \
-Denable-gtk-doc-html=no \
-Denable-gtk3=yes \
-Dwith-gtk=3 \
-Denable-introspection=yes \
-Denable-notifications=yes \
-Ddisable-libsystemd-login=yes \
-Ddisable-vulkan=yes \
-Ddisable-wayland=yes \
-Dbuild=${ARCH}-zenwalk-linux \
"
# Do we have custom $CONFIG ? then overwrite it here...
if [ -e ${CWD}/configure.sh ]; then
	. ${CWD}/configure.sh 
fi
sleep 2
echo -e "${BOLDCYAN}Configure options are : ${CONFIG} ${COLOR_RESET}"
		mkdir build
		meson --prefix ${PREFIX} --libdir ${LIBINSTALLDIR} build || exit 1
		(
			meson configure ${CONFIG} build
			sed -i "/^ COMMAND = \\/usr\\/bin\\/g-ir-scanner/s/-lyaml //" build/build.ninja
			ninja -C build
			DESTDIR=${PKG} ninja -C build install
		)

# PYTHON
elif [ -e ${SRC}/setup.py ]; then
echo -e "${BOLDCYAN}Building and installing source (PYTHON)${COLOR_RESET}"
export CONFIG="\
--prefix=${PREFIX} --root=${PKG} \
"
# Do we have custom $CONFIG ? then overwrite it here...
if [ -e ${CWD}/configure.sh ]; then
	. ${CWD}/configure.sh 
fi
echo -e "${BOLDCYAN}Configure options are : ${CONFIG} ${COLOR_RESET}"
sleep 2
		# python setup.py install ${CONFIG} 
        python3 setup.py install ${CONFIG} || exit

# PERL
elif [ -e ${SRC}/Makefile.PL ]; then
echo -e "${BOLDCYAN}Building and installing source (PERL)${COLOR_RESET}"
export CONFIG=""
# Do we have custom $CONFIG ? then overwrite it here...
if [ -e ${CWD}/configure.sh ]; then
	. ${CWD}/configure.sh 
fi
echo -e "${BOLDCYAN}Configure options are : ${CONFIG} ${COLOR_RESET}"
sleep 2
		perl Makefile.PL ${CONFIG} || exit 1
		make
		make install DESTDIR=${PKG}
		
# CMAKE
elif ls ./*[Cc][Mm]ake* ; then
echo -e "${BOLDCYAN}Building and installing source (CMAKE)${COLOR_RESET}"
export CONFIG="\
-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 \
-DCMAKE_BUILD_TYPE=Release ..
"
# Do we have custom $CONFIG ? then overwrite it here...
if [ -e ${CWD}/configure.sh ]; then
	. ${CWD}/configure.sh 
fi
echo -e "${BOLDCYAN}Configure options are : ${CONFIG} ${COLOR_RESET}"
sleep 2
		mkdir build
		(
			cd build
			cmake \
			${CONFIG} || exit 1
			makebuild
		)

# CLASSIC CONFIGURE
else 
echo -e "${BOLDCYAN}Building and installing source (standard MAKE)${COLOR_RESET}"
# Do we have custom $CONFIG ? then overwrite it here...
	if [ -e ${CWD}/configure.sh ]; then
		. ${CWD}/configure.sh 
	fi
echo -e "${BOLDCYAN}Configure options are : ${CONFIG} ${COLOR_RESET}"
sleep 2
		if [ ! -e ${SRC}/configure ]; then
			./autogen.sh || autoreconf -fiv
		fi
		
		if [ -e ${SRC}/configure ]; then
			./configure \
			  ${CONFIG}  || exit 1
			  
			  makebuild  || exit 1
		else
		# pure Makefile ?
			  makebuild || exit 1
		fi
fi

# In case local is used
if [ -d ${PKG}${PREFIX}/local/bin ]; then 
	mkdir -p ${PKG}${PREFIX}/bin
	mv ${PKG}${PREFIX}/local/bin/* ${PKG}${PREFIX}/bin/
fi
if [ -d ${PKG}${PREFIX}/local/sbin ]; then 
	mkdir -p ${PKG}${PREFIX}/sbin
	mv ${PKG}${PREFIX}/local/sbin/* ${PKG}${PREFIX}/sbin/
fi
if [ -d ${PKG}${PREFIX}/local/include ]; then 
	mkdir -p ${PKG}${PREFIX}/include
	mv ${PKG}${PREFIX}/local/include/* ${PKG}${PREFIX}/include/
fi
if [ -d ${PKG}${PREFIX}/local/lib${LIBDIRSUFFIX} ]; then 
	mkdir -p ${PKG}${PREFIX}/lib${LIBDIRSUFFIX}
	mv ${PKG}${PREFIX}/local/lib${LIBDIRSUFFIX}/* ${PKG}${PREFIX}/lib${LIBDIRSUFFIX}/
fi
if [ -d ${PKG}${PREFIX}/local/lib ]; then 
	mkdir -p ${PKG}${PREFIX}/lib${LIBDIRSUFFIX}
	mv ${PKG}${PREFIX}/local/lib/* ${PKG}${PREFIX}/lib${LIBDIRSUFFIX}/
fi
rm -rf ${PKG}/usr/local

# 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

# some custom post build instructions

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

cd ${CWD}


# 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
fi

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
	
# dotnew the configs

for f in $( find $PKG/etc -type f ) ; do mv $f $f.new ; done

	cat << "END" >> ${PKG}/install/doinst.sh 	
config() {
  NEW="$1"
  OLD="$(dirname $NEW)/$(basename $NEW .new)"
  # If there's no config file by that name, mv it over:
  if [ ! -r $OLD ]; then
    mv $NEW $OLD
  elif [ "$(cat $OLD | md5sum)" = "$(cat $NEW | md5sum)" ]; then
    # toss the redundant copy
    rm $NEW
  fi
  # Otherwise, we leave the .new copy for the admin to consider...
}
END

(
cd ${PKG}
	for dotnew in $( find . -type f -name "*.new" ) ; do 
cat >> ${PKG}/install/doinst.sh << END
config ${dotnew#./}
END
	done	
)

echo -e "${BOLDCYAN}Creating package...${COLOR_RESET}"
cd ${PKG}
chown -R root.root .
find . -perm 0777 -exec chmod 755 {} \;
find . -perm 0775 -exec chmod 755 {} \;
find . -perm 0666 -exec chmod 644 {} \;
find . -perm 0664 -exec chmod 644 {} \;
find . -perm 4777 -exec chmod 4755 {} \;
find . -perm 4775 -exec chmod 4755 {} \;

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}
