#!/bin/bash

# This script configures the mirrors that are used in
# /etc/slapt-get/slapt-getrc and /etc/slapt-get/slapt-srcrc

check_for_root(){
	if [ "$UID" != "0" ]; then
		echo "`eval_gettext 'You need root privileges to run this'`"
		exit 1
	fi
}

init(){
	# Translations only work with utf8 locales
	if [ ! `echo $LANG | grep -i utf` ]; then
		LANG=C
	fi

	# Gettext internationalization
	export TEXTDOMAIN="reposetup"
	export TEXTDOMAINDIR="/usr/share/locale"
	. gettext.sh

	# create temp dir
	TEMPDIR="$(mktemp -d -p /tmp reposetup.XXXXXXXX)"
	cd $TEMPDIR

	# Path to the salixtools shared files
	salixtoolsdir="/usr/share/salixtools/"

	# Paths to the slapt-* configuration files
	SLAPTGETRC="/etc/slapt-get/slapt-getrc"
	SLAPTSRCRC="/etc/slapt-get/slapt-srcrc"

	# Paths to the slapt-* binaries
	SLAPTGET="/usr/sbin/slapt-get"
	SLAPTSRC="/usr/bin/slapt-src"

	# Set to interactive mode by default
	INTERACTIVE=1

	# Refresh the mirror list from an online location by default
	REFRESHMIRRORS=1

	# Set to update repos by default (or ask for update if in
	# interactive mode)
	UPDATE=1
}

checkdefaults(){
	# determine arch
	case "$( uname -m )" in
		i?86) export arch=i486 ;;
		arm*) export arch=arm ;;
		*) export arch=$( uname -m ) ;;
	esac
	
	# slackware arm has a slightly different directory name
	if [ $arch == "arm" ]; then
		slackdir="slackwarearm"
	else
		slackdir="slackware"
	fi	

	# read salix version
	if [ -f $salixtoolsdir/salix-version ]; then
		version=$( cat $salixtoolsdir/salix-version )
	else
		echo "ERROR: $salixtoolsdir/salix-version not found"
		exit 11
	fi

	CURRENTREPO=""

	# slapt-getrc
	if [ -f $SLAPTGETRC ]; then
		CURRENTREPO=$( cat $SLAPTGETRC | grep "^SOURCE=" | grep ":PREFERRED$" | sed "s/^SOURCE=\(.*\)\/$arch\/$version\/:PREFERED/\1/" )
		SLAPTGETWORKINGDIR=$( cat $SLAPTGETRC | grep "^WORKINGDIR=" | head -n 1 | sed "s/^WORKINGDIR=\(.*\)/\1/" )
		SLAPTGETEXCLUDE=$( cat $SLAPTGETRC | grep "^EXCLUDE=" | head -n 1 | sed "s/^EXCLUDE=\(.*\)/\1/" )
	else
		SLAPTGETWORKINGDIR="/var/slapt-get"
		ALLEXCLUDE="^aaa_elflibs,^aaa_base,^devs,^glibc.*,^kernel-.*,^udev,^rootuser-settings,^zzz-settings.*"
		if [ $arch == "arm" ]; then
			SLAPTGETEXCLUDE="${ALLEXCLUDE}"
		elif [ $arch == "x86_64" ]; then
			SLAPTGETEXCLUDE="${ALLEXCLUDE},-i?86-"
		else
			SLAPTGETEXCLUDE="${ALLEXCLUDE},-x86_64-"
		fi
	fi
	
	# keep CUSTOM slapt-get repos in a temporary file
	grep "CUSTOM$" $SLAPTGETRC > $TEMPDIR/custom

	# slapt-srcrc
	if [ -f $SLAPTSRCRC ]; then
		CURRENTREPO=$( cat $SLAPTSRCRC | grep "^SOURCE=" | grep "slkbuild" | sed "s/^SOURCE=\(.*\)\/slkbuild\/\(.*\)/\1/" )
		SLAPTSRCBUILDDIR=$( cat $SLAPTSRCRC | grep "^BUILDDIR=" | head -n 1 | sed "s/^BUILDDIR=\(.*\)/\1/" )
		SLAPTSRCPKGEXT=$( cat $SLAPTSRCRC | grep "^PKGEXT=" | head -n 1 | sed "s/^PKGEXT=\(.*\)/\1/" )
	else
		SLAPTSRCBUILDDIR="/usr/src/slapt-src"
		SLAPTSRCPKGEXT="txz"
	fi
}

# The interactive section
interactive(){

	list="$( cat $salixtoolsdir/reposetup/repomirrors )"
	
	# Display server selection dialog
	repo="$(eval dialog \
	--stdout \
	--title \"`eval_gettext 'Select repository mirror'`\" \
	--default-item \"$CURRENTREPO\" \
	--ok-label \"`eval_gettext 'Select'`\" \
	--cancel-label \"`eval_gettext 'Cancel'`\" \
	--menu \
	\"\\n`eval_gettext 'Please select your preferred repository mirror. The country code of where the mirror is located is shown on the right. Your selection will be applied to the /etc/slapt-get/slapt-getrc and /etc/slapt-get/slapt-srcrc files:'`\\n\\n`eval_gettext 'WARNING: Any changes you have manually made in the SOURCE lines of those files will be lost!'`\" 20 80 11 $list )"

	# Don't do anything if Cancel or the close button was pressed
	retval=$?
	if [ $retval -eq 1 ] || [ $retval -eq 255 ]; then
		cleanup
		exit 0
	fi
}

updatecache(){
	if [ $INTERACTIVE -eq 1 ]; then
		answer="$(eval dialog \
		--stdout \
		--title \"`eval_gettext 'Update package caches?'`\" \
		--yes-label \"`eval_gettext 'Update'`\" \
		--no-label \"`eval_gettext 'Do not update'`\" \
		--yesno \"`eval_gettext 'Would you like to update the package and SlackBuild caches now?'`\" \
		0 0 )"
		retval=$?
	else
		retval=0
	fi
	if [ $retval -eq 0 ]; then
		$SLAPTGET --update && $SLAPTSRC --update
	fi
}

configslaptget() {
	(
	echo "# Working directory for local storage/cache."
	echo "WORKINGDIR=$SLAPTGETWORKINGDIR"
	echo ""
	echo "# Exclude package names and expressions."
	echo "# To exclude pre and beta packages, add this to the exclude:"
	echo "#   [0-9\_\.\-]{1}pre[0-9\-\.\-]{1}"
	echo "EXCLUDE=$SLAPTGETEXCLUDE"
	echo ""
	echo "# The Slackware repositories, including dependency information"
	echo "SOURCE=$repo/$arch/$slackdir-$version/:OFFICIAL"
	echo "SOURCE=$repo/$arch/$slackdir-$version/extra/:OFFICIAL"
	echo ""
	echo "# The Salix repository"
	echo "SOURCE=$repo/$arch/$version/:PREFERRED"
	echo ""
	echo "# Local repositories"
	) > $SLAPTGETRC

	cat $TEMPDIR/custom >> $SLAPTGETRC
}

configslaptsrc(){
	(
	echo "BUILDDIR=$SLAPTSRCBUILDDIR"
	echo "PKGEXT=$SLAPTSRCPKGEXT"
	echo "SOURCE=$repo/slkbuild/$version/"
	echo "SOURCE=$repo/sbo/$version/"
	) > $SLAPTSRCRC
}

usage(){
echo "`eval_gettext 'USAGE:'` reposetup [[-m `eval_gettext 'mirror'`] [-l] [-n]]"
echo
echo "`eval_gettext 'OPTIONS:'`"
echo "    -m mirror,  `eval_gettext 'Specify a repository mirror manually'`"
echo "    -l,         `eval_gettext 'Use local mirror list and do not download a new one'`"
echo "    -n,         `eval_gettext 'Do not update/ask for updating the package caches'`"
echo "    -p,         `eval_gettext 'Print currently selected mirror'`"
echo "    -h,         `eval_gettext 'This help message'`"
}

checkoptions(){
	while getopts ":hm:lnp" flag
	do
		# if switch is unknown or if asking for help
		if [ $flag = "?" ] || [ $flag = "h" ]; then
			usage
			cleanup
			exit 0
		fi
		if [ $flag = "m" ]; then
			# the repo URL has to be an http:// or ftp://
			# or even a file:// address for local files.
			# we're only doing very basic address checking
			# here
			if [[ "$OPTARG" == http://[[:alnum:]]* ]] \
				|| [[ "$OPTARG" == ftp://[[:alnum:]]* ]] \
				|| [[ "$OPTARG" == file:///[[:alnum:]]* ]] ; then
				INTERACTIVE=0
				# remove trailing slashes
				repo="`echo \"$OPTARG\" | sed 's|/*$||g'`"
			else
				usage
				cleanup
				exit 1
			fi
		fi
		if [ $flag = "l" ]; then
			REFRESHMIRRORS=0
		fi
		if [ $flag = "n" ]; then
			UPDATE=0
		fi
		if [ $flag = "p" ]; then
			if [[ -n $CURRENTREPO ]]; then
				echo $CURRENTREPO
				cleanup
				exit 0
			else
				cleanup
				exit 1
			fi
		fi
	done
	
	# we shift positions in $@ so that we discard all previous switches
	shift $((OPTIND-1))

	# There should be no more arguments
	if [ $# -gt 0 ]; then
		echo "`eval_gettext 'ERROR: Too many arguments'`" >&2
		usage
		cleanup
		exit 1
	fi
}

refreshmirrors(){
# clean up any old remnants just in case
rm -f $salixtoolsdir/reposetup/repomirrors.new

# If there is a repo already set, use it
if [[ -z $CURRENTREPO ]]; then
	REFRESH=1
else
	message="`eval_gettext 'Refreshing mirror list from'` $CURRENTREPO/MIRRORS"
	dialog --infobox "$message" 0 0
	wget -q $CURRENTREPO/MIRRORS -O $salixtoolsdir/reposetup/repomirrors.new
	retval=$?
	if [ $retval -eq 0 ]; then
		REFRESH=0
	else
		message="`eval_gettext 'Getting mirror list failed'`"
		dialog --infobox "$message" 0 0
		sleep 1
		REFRESH=1
	fi
fi

# if the already selected repo does not work, try to use any of the
# other ones that are listed in the repomirrors file that is already
# there
if [ $REFRESH -eq 1 ]; then
	while read line; do
		rm -f $salixtoolsdir/reposetup/repomirrors.new
		REPO=$( echo $line | sed "s/^\(.*\) [A-Z][A-Z]/\1/" )
		message="`eval_gettext 'Refreshing mirror list from'` $REPO/MIRRORS"
		dialog --infobox "$message" 0 0
		wget -q $REPO/MIRRORS -O $salixtoolsdir/reposetup/repomirrors.new
		retval=$?
		if [ $retval -eq 0 ]; then
			break
		else
			message="`eval_gettext 'Getting mirror list failed'`"
			dialog --infobox "$message" 0 0
			sleep 1
		fi
	done < $salixtoolsdir/reposetup/repomirrors
fi

# compare the old and new repomirrors files
diff -q \
	$salixtoolsdir/reposetup/repomirrors \
	$salixtoolsdir/reposetup/repomirrors.new > /dev/null
retval=$?
if [ $retval -eq 1 ]; then
	mv $salixtoolsdir/reposetup/repomirrors.new \
		$salixtoolsdir/reposetup/repomirrors
else
	rm -f $salixtoolsdir/reposetup/repomirrors.new
fi
}

cleanup(){
	rm -rf $TEMPDIR
}

# This is the main thing!
init
checkdefaults
checkoptions $@
check_for_root

# Refresh mirror list (only in interactive mode)
[ $INTERACTIVE -eq 1 ] && [ $REFRESHMIRRORS -eq 1 ] && refreshmirrors

# Run interactive session
[ $INTERACTIVE -eq 1 ] && interactive

# Apply selected settings
configslaptget
configslaptsrc

# Update package caches
[ $UPDATE -eq 1 ] && updatecache

# clean up
cleanup

