#!/bin/bash
#  Copyright (c) 2016 by NuTyX team (http://nutyx.org)
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
#  USA.
#
##


usage() {
echo "
Recommended use:

You should mount the '$PROJECT' git as bind option (--bind) in your personal account

Example if your personal account is 'tnut' and
this chroot NuTyX is installed in '/mnt/lfs', proceed as follow

1. clone this project as 'tnut' user:
   cd ~
   git clone git://github.com/NuTyX/$PROJECT.git

2. your git is now in following directory:
   '/home/tnut/$PROJECT'


3. Delete this git in your chroot and create an empty folder
    rm -r /mnt/lfs/root/$PROJECT
    mkdir -p /mnt/lfs/root/$PROJECT

4. Mount your '$PROJECT' git projet as bind option INTO your chroot
    mount -o bind /home/tnut/$PROJECT /mnt/lfs/root/$PROJECT

5. Make your git operation in 'tnut' user

Option: you could add this alias into your chroot root .bashrc
    alias $COLLECTION='_() { cd $GIT; bash scripts/$COLLECTION \$@; cd -; };_ \$@'

It will make your life easier. To build any port from the collection $COLLECTION,
you will just have to type:
    $COLLECTION  <name_of_the_port>
"

}
print_help()
{
	echo "usage: $COLLECTION [option]"
	echo "options:"
	echo "   -a,   --all                 will build all the ports of the '$COLLECTION' collection in the right order"
	echo "   -l,   --list                will list all the ports of the '$COLLECTION' collection in the right order"
	echo "  -ru,   --remove-url          remove the URL part in /etc/cards.conf file for the '$COLLECTION' collection"
	echo "  -cp,   --check-ports         check if new ports are available"
	echo "  -cb,   --check-binaries      check if binaries are uptodate"
	echo "   -d,   --dry                 check if binaries are different then the ports but dont build anything"
	echo "   -s,   --sync                synchronise binaries from rsync server location"
	echo "   -c,   --config              printout the configuration"
	echo "   -h,   --help                print help and exit"
	echo "   -v,   --version             print version and exit"
	echo "   -u,   --usage               print the recommended way of using the '$COLLECTION' script"
}
list_ports() {
	cd $PORT_BASE && find . -name Pkgfile -follow -printf "%h\n" | sed 's|^./||g' | sort
}
check_binaries()
{
	check_location
	check_config_file
	if [ ! -d ${BINARY_BASE} ]; then
		echo "The directory ${BINARY_BASE} doesn't exist"
		echo "Please fix your setting in /etc/cards.conf.d/$COLLECTION.conf file"
		echo "Variable 'BINARY_BASE'"
		exit 1
	fi
	cd ${BINARY_BASE}
	for DIR in *
	do
		if [ -d $DIR ]; then
			if [ ! -d $PORT_BASE/$DIR ]; then
				echo "'$DIR' should be removed and delete from the .PKGREPO file"
				rm -vr $DIR
				[ -f .PKGREPO ] && sed -i "/#$DIR#/d" .PKGREPO
			else
				rsync -au  --exclude="*cards.tar*" --exclude=".PKGREPO" --delete \
					${PORT_BASE}/$DIR/ ${BINARY_BASE}/$DIR/
			fi
		fi
	done
	cd - > /dev/null
}
check_ports()
{
	check_location
	check_config_file
	if [ ! -d ${PORT_BASE} ]; then
		echo "The directory ${PORT_BASE} doesn't exist"
		echo "Please fix your setting in /etc/cards.conf.d/$COLLECTION.conf file"
		echo "Variable 'PORT_BASE'"
		exit 1
	fi
	sync_pkgmk_conf
	cd ${PORT_BASE}
	for DIR in *
	do
		if [ ! -d ${BINARY_BASE}/$DIR ] || [ ! -f ${BINARY_BASE}/$DIR/Pkgfile ]; then
			echo "'$DIR' should be added"
			rsync -av --delete ${PORT_BASE}/$DIR/ ${BINARY_BASE}/$DIR/
		else
			rsync -au  --exclude="*cards.tar*" --exclude=".PKGREPO" --delete \
				${PORT_BASE}/$DIR/ ${BINARY_BASE}/$DIR/
		fi
		if [ ! -f ${BINARY_BASE}/$DIR/.PKGREPO ];then
			echo "$DIR should be build"
		fi
	done
	cd - > /dev/null
}
check_diff()
{
	check_location
	check_config_file
	ports_list=`mktemp` || exit 1
	binaries_list=`mktemp` || exit 1
	output=`mktemp` || exit 1
	output_sorted=`mktemp` || exit 1
	found="no"

	cards list -p|grep $BINARY_BASE|sed "s@$BINARY_BASE/@@" >> $binaries_list
	list_ports >> $ports_list

	for binary_package in `cat $binaries_list | gawk '{ print $1 }'`; do
		binary_package_version=`cat $binaries_list | grep "^$binary_package " | gawk '{ print $2 }'| cut -d "-" -f1`
		binary_package_release=`cat $binaries_list | grep "^$binary_package " | gawk '{ print $2 }'| cut -d "-" -f2`
		if [ "$binary_package_version" == "" ]; then
			base_binary_package=`echo $binary_package | cut -d "-" -f1`
			if [ "$base_binary_package" != "$binary_package" ]; then
				binary_package_version=`cat $binaries_list | grep "^$base_binary_package " | gawk '{ print $2 }'| cut -d "-" -f1`
				binary_package_release=`cat $binaries_list | grep "^$base_binary_package " | gawk '{ print $2 }'| cut -d "-" -f2`
			fi
		fi
		binary_version=`echo $binary_package_version-$binary_package_release`
		package=$binary_package
		if [ -f $PORT_BASE/$package/Pkgfile ]; then
			base_package=`echo $package | cut -d "-" -f1`
			cd $PORT_BASE/$package
			get_port_version
			port_version=`echo $version-$release`
			if [ "$binary_version" != "$port_version" ]; then
				echo "$package $port_version $binary_version" >> $output
				found="yes"
			fi
		fi
	done
	if [ "$found" = "yes" ]; then
		echo "Name Port Compiled" >> $output_sorted
		sort $output >> $output_sorted
		column -t $output_sorted
	fi
}
check_port_name() {
	check_config_file
	if [ ! -d "$PORT_BASE/$1" ]; then
		echo "I dont know the port $1"
		exit 1
	fi
}
check_collection_exist() {
	if [ ! -d "$COLLECTION" ]; then
		echo "I dont know the collection $COLLECTION"
		exit 1
	fi
}
parse_options() {
	while [ "$1" ]; do
		case $1 in
			-l|--list)
				check_ports
				list_binaries
				exit 0
				;;
			-a|-all)
				check_ports
				check_binaries
				build_binaries
				exit 0
				;;
			-cp|--check-ports)
				check_ports
				exit 0
				;;
			-cb|--check-binaries)
				check_binaries
				exit 0
				;;
			-cd|--check-diff|-d|--dry)
				DRY="yes"
				check_ports
				check_binaries
				build_binaries
				exit 0
				;;
			-ru|--remove-url)
				check_root
				check_tools
				check_config_file
				remove_url
				exit 0
				;;
			-s|--sync)
				sync_binaries
				exit 0;;
			-c|--config)
				check_root
				check_tools
				check_config_file
				echo "Your config is:
NuTyX name    : $RSYNC_NUTYX_NAME
NuTyX version : $RSYNC_NUTYX_VERSION
BINARY_BASE   : $BINARY_BASE
PORT_BASE     : $PORT_BASE
"
				exit 0;;

			-h|--help)
				print_help
				exit 0;;

			-v|--version)
				echo "$COLLECTION $BUILD_PORT_VERSION"
                                exit 0 ;;

			-u|--usage)
				usage
				exit 0;;

			*)
				check_port_name $1
				;;

		esac
		shift
	done
}
check_tools () {
	if ! (`which cards > /dev/null`); then
		echo "'cards' not available"
		exit 1
	fi
	if ! (`which pkgmk > /dev/null`); then
		echo "'cards.devel' not available"
		exit 1
	fi
	if ! (`which rsync > /dev/null`); then
		echo "'rsync' not available"
		exit 1
	fi
	if ! (`which gawk > /dev/null`); then
		echo "'gawk' not available"
		exit 1
	fi
}
check_root () {
	if [ ! "$UID" == "0" ]; then
		echo "You are not 'root'"
		exit 1
	fi
}
check_location () {
if [ ! -d .git ] && [ ! -d scripts ]; then
	echo "Make shure you are at the root of the git"
	echo "Your are in: $GIT"
	exit 1
fi
}
check_user () {
if [ "$UID" == "0" ] && [ -O scripts ] ; then
	echo "your are 'root' account
Means you are not suppose to 'git pull' this git project"
	usage
	echo "I quit for now

"
	exit 1
fi
}
get_binary_directory() {
	local DIR
	DIR=`cards config|grep Directory| cut -d " " -f3|grep ${COLLECTION}$|sed "s/\/${COLLECTION}$//"|head -1`
	if [ ! -z ${DIR} ]; then
		BINARY_DIR=${DIR}
	else
		BINARY_DIR=${RSYNC_NUTYX_VERSION}
	fi
}
get_binary_version() {
	local version release
	cd $BINARY_BASE/$package
	version=`head -1 .PKGREPO|cut -d "#" -f3`
	release=`head -1 .PKGREPO|cut -d "#" -f4`
	binary_version=$version-$release
}
get_port_version() {
	local port base_port PORTS_DIR tmprel
	port=/$PORT_BASE/$package
	PORTS_DIR=$PORT_BASE
	base_port=`echo $package | cut -d "-" -f1`
	cd $port
	unset version
	unset release
	[ -f ../${PKGMK_CONFFILE} ] && . ../${PKGMK_CONFFILE}
	. Pkgfile
	[ ! -z $release ] && tmprel=$release
	if [ -z $version ] && [ "$base_port" != "$package" ] ; then
		if [ -f $PORTS_DIR/$base_port/Pkgfile ]; then
			cd $PORTS_DIR/$base_port
			. Pkgfile
		fi
	fi
	[ -z $release ] && release=1
	[ ! -z $tmprel ] && release=$tmprel
	port_version="$version-$release"
}
check_config_file () {
	get_binary_directory
	if [ ! -f /etc/cards.conf.d/$COLLECTION.conf ] ; then
		echo "Create $COLLECTION.conf file"
		[ ! -d /etc/cards.conf.d ] && mkdir -p /etc/cards.conf.d
		echo "PORT_BASE=$GIT/$COLLECTION
BINARY_BASE=${BINARY_DIR}/$COLLECTION" > /etc/cards.conf.d/$COLLECTION.conf
	fi

	. /etc/cards.conf.d/$COLLECTION.conf || exit 1

	[ ! -d $BINARY_BASE ] && mkdir -p $BINARY_BASE
	if [  "$BINARY_BASE" == "$PORT_BASE" ]; then
		echo "Correct your $COLLECTION.conf file
BINARY_BASE and PORT_BASE should NEVER be equal
BINARY_BASE=$BINARY_BASE
PORT_BASE=$PORT_BASE
I quit for now
"
		exit 1
	fi
	if [ -f /var/lib/pkg/nutyx-version ]; then
		RSYNC_NUTYX_VERSION=`cat /var/lib/pkg/nutyx-version|grep version|sed "s/version //"| sed "s/ //g"`
		RSYNC_NUTYX_NAME=`cat /var/lib/pkg/nutyx-version|grep name|sed "s/name //"| sed "s/ //g"`
	else
		echo "/var/lib/pkg/nutyx-version file not exist
I quit for now
"
		exit 1
	fi
	if [ -z $RSYNC_NUTYX_VERSION ]; then
		echo "Dont know the version you want to rsync
Check the /var/lib/pkg/nutyx-version, should have a
line like:

name houaphan
version 8.0

"
		exit 1
	fi
}
sync_binaries () {
	check_tools
	check_config_file
	check_collection_exist
	remove_url
	rsync -av --delete ${RSYNC_SERVER}/${ARCH}/${RSYNC_NUTYX_VERSION}/$COLLECTION/ \
	$BINARY_BASE/
}
sync_pkgmk_conf() {
	if [ -f ${PORT_BASE}/${PKGMK_CONFFILE} ]; then
		rsync -a ${PORT_BASE}/${PKGMK_CONFFILE} \
		${BINARY_BASE}/${PKGMK_CONFFILE}
	else
		rm -f ${BINARY_BASE}/${PKGMK_CONFFILE}
	fi

}
remove_url () {
	local URL
	URL="`cat /etc/cards.conf|grep \"^dir[ ]*${BINARY_BASE}|\"| cut -d '|' -s -f2`"
	if [ ! -z "$URL" ]; then
		sed -i "s@${BINARY_BASE}|${URL}@${BINARY_BASE}@" /etc/cards.conf
	fi
}
build_binaries () {
	local package port_version binary_version currentdir
	currentdir=$PWD
	sync_pkgmk_conf
	for i in `cards level -I |grep ${BINARY_BASE}/|cut -d " " -f2`
	do
		package=`basename $i`
		if [  -z "`ls ${BINARY_BASE}/$package/*$ARCH.cards.tar.xz 2>/dev/null `" ];then
			cd $currentdir
			[ "$DRY" == "yes" ] && continue
			bash scripts/$COLLECTION $package|| exit 1
			continue
		fi
		if [ ! -f ${BINARY_BASE}/$package/.PKGREPO ]; then
			cd $currentdir
			[ "$DRY" == "yes" ] && continue
			bash scripts/$COLLECTION $package|| exit 1
			continue
		fi
		if [ ! -z "`diff ${BINARY_BASE}/$package/Pkgfile ${PORT_BASE}/$package/Pkgfile`" ]; then
			echo " ${BINARY_BASE}/$package/Pkgfile AND ${PORT_BASE}/$package/Pkgfile are different ...WILL BUILD NEW.."
			cd $currentdir
			[ "$DRY" == "yes" ] && continue
			bash scripts/$COLLECTION $package || exit 1
			continue
		fi
		get_port_version
		get_binary_version
		if [ "$port_version" != "$binary_version" ]; then
			echo "$package: Port: $port_version, Binary: $binary_version"
			cd $currentdir
			[ "$DRY" == "yes" ] && continue
			bash scripts/$COLLECTION $package || exit 1
			continue
		fi
		[ "$DRY" == "yes" ] || echo "WILL NOT BUILD '$package' AGAIN.."
	done
}
list_binaries () {
	cards level -I |grep ${BINARY_BASE}
}
main() {
	parse_options "$@"
	check_tools
	check_location
	check_user
	check_config_file
	check_collection_exist
	if [ $# -lt 1 ]; then
		print_help
		usage
		exit 0
	fi
	sync_pkgmk_conf
	rsync -av --exclude '.*.swp'  --exclude '*~' \
	--delete-after ${PORT_BASE}/$1/ \
	${BINARY_BASE}/$1/

	chown -R 0:0 ${BINARY_BASE}/$1/

	cards create -r $1

}
BUILD_PORT_VERSION=2.3.3.0
DRY="no"
ARCH=`uname -m`
RSYNC_SERVER="rsync://downloads.nutyx.org/nutyx"
COLLECTION="`basename $0`"
GIT=`pwd`
PROJECT="`basename $GIT`"
PKGMK_CONFFILE=".pkgmk.conf"
main "$@"
