#!/bin/bash
gpkg build $1 || exit 1
VERSION=`cat VERSION`
if [ "$VERSION" == "" ]; then
	VERSION=0.0
fi
BUILD=$VERSION.$BUILD_NUMBER
mkdir -p $GVM_ROOT/pkgs/pkg.gvm/$1/current
cp $GVM_ROOT/pkgsets/$gvm_go_name/$gvm_pkgset_name/pkg.gvm/$1/$BUILD/manifest $GVM_ROOT/pkgs/pkg.gvm/$1/current/manifest
exit 0

. $GVM_ROOT/scripts/functions

show_usage() {
  echo "Usage: gvm pkg install Package [options]"
  echo "    -v, --version=VERSION     Set the package version to install."
  echo "    -s, --source=SORUCE       Specify the source for this package."
  echo "    --strict                  Only use installed packages."
  echo "    -a, --all                 Update all dependencies."
  echo "    -h, --help                Display this message."
}

function read_command_line() {
	[[ "$1" == "" ]] && 
		display_error "Please specify package name"

	# Get package name
	package_name=$1
	sources=`cat $GVM_ROOT/config/sources`
	shift
	version=$1
	strict="true"
	gvm_go_path=$GVM_ROOT/pkgsets/$gvm_go_name/$gvm_pkgset_name
	cache_dir=$GVM_ROOT/archive/package/$package_name
	tmp_dir=$GVM_ROOT/tmp/$$
	source_dir=$tmp_dir/$package_name/src/$package_name
	build_dir=$tmp_dir/$package_name/build
	# TODO: Remove hack after change to gvm_build
	mkdir -p $GVM_ROOT/pkgs/pkg.gvm/$package_name/current
}

function download_package() {
	if [ -d $cache_dir ]; then
		cd $cache_dir && git pull &> /dev/null
		return
	fi
	echo "Downloading $package_name..."
	for source in $sources; do
		echo "Trying $source"
		git clone $source/$package_name $cache_dir > /dev/null 2>&1
		if [ "$?" == "0" ]; then
			echo $source > $cache_dir/GVM_SOURCE
			return
		fi
	done
	display_error "Could not find $package_name in any sources"
}

function update_package_cache() {
	cd $cache_dir && git pull > /dev/null 2>&1 ||
		display_error "Failed to update source"
}

function copy_tmp_source() {
	rm -rf $source_dir
	if [ "$version" != "" ]; then
		echo "Checking out $version"
		git clone $cache_dir $source_dir > /dev/null 2>&1
		cd $source_dir && git checkout $version > /dev/null 2>&1 ||
			return 1
	else
		git clone $cache_dir $source_dir > /dev/null 2>&1
	fi

	cd $source_dir
	git describe --exact-match > /dev/null 2>&1
	if [ "$?" == "0" ]; then
		git_tag=`git describe --exact-match`
		git_version=`echo $git_tag | awk '{ n=split($1,path,"_"); print path[n] }'`
		if [ "$BUILD_NUMBER" == "" ]; then
			BUILD_NUMBER=$git_version
		fi
	fi
}

function setup_build_env() {
	rm -rf $build_dir && mkdir -p $build_dir
	copy_tmp_source
	if [ "$?" != "0" ]; then
		update_package_cache
		copy_tmp_source ||
			display_error "Invalid version"	
	fi
	if [[ -f $source_dir/VERSION ]]; then
		SOURCE_VERSION=`cat $source_dir/VERSION`
	fi

	if [[ -n $BUILD_NUMBER ]]; then
		BUILD_NUMBER="$SOURCE_VERSION.$BUILD_NUMBER"
	else
		if [[ "$SOURCE_VERSION" != "" ]]; then
			BUILD_NUMBER="$SOURCE_VERSION.src"
		else
			BUILD_NUMBER="src"
		fi
	fi
}

function install_dep() {
	[[ "$strict" == "true" ]] && display_error "Missing dependancy ($1) and strict mode is set"
	passthrough_options=""
	[[ "$source" != "" ]] && passthrough_options="--source=$source "$passthrough_options
	[[ "$all_deps" == "true" ]] && passthrough_options="--all "$passthrough_options
	gvm pkg install $1 $passthrough_options ||
		display_error "Failed to install dependency $1"
}

function load_dep() {
	if [[ "$all_deps" == "true" ]]; then
		install_dep $1
	fi

	CUR_PKG=$gvm_go_path/pkg.gvm/$1/current
	if [ -e "$CUR_PKG/BUILD_VERSION" ]; then
		echo "pkg $1 `cat $CUR_PKG/BUILD_VERSION`" >> $build_dir/manifest
	else
		install_dep $1
	fi
	cp -rf $CUR_PKG/pkg $build_dir
}

function check_deps() {
	export GOPATH=$build_dir
	echo ":source `cat $cache_dir/GVM_SOURCE`" >> $build_dir/manifest
	if [ -f "$source_dir/Package.gvm" ]; then
		for line in `cat $source_dir/Package.gvm | grep ^pkg | awk '{ print $2 }'`; do
			load_dep $line
		done
	fi
	echo ":complete" >> $build_dir/manifest
}

function copy_source() {
	git clone $source_dir $gvm_go_path/pkg.gvm/$package_name/$BUILD_NUMBER/ &> /dev/null
	#mkdir -p $gvm_go_path/pkg.gvm/$package_name/$BUILD_NUMBER
	#cp -rf $source_dir $gvm_go_path/pkg.gvm/$package_name/$BUILD_NUMBER/
}

function build_package() {
	echo "Installing $package_name-$BUILD_NUMBER..."
	echo "$BUILD_NUMBER" > $build_dir/BUILD_VERSION
	export BUILD_NUMBER
	cd $source_dir && gvmake > $build_dir/build.log 2>&1
	if [ $? -ne 0 ]; then
		echo "ERROR: Failed to build"
		cat "$build_dir/build.log"
		exit 1
	fi
        echo "Running tests..."
        cd $source_dir && gvmake test >> $build_dir/build.log 2>&1
        if [ $? -ne 0 ]; then
                echo "ERROR: Failed tests"
                cat "$build_dir/build.log"
                exit 1
        fi
}

function install_package() {
	mkdir -p $gvm_go_path/pkg.gvm/$package_name/$BUILD_NUMBER ||
		display_error "Failed to create $gvm_go_path/pkg.gvm/$package_name/$BUILD_NUMBER"
	cp -r $build_dir/* $gvm_go_path/pkg.gvm/$package_name/$BUILD_NUMBER ||
		display_error "Failed to copy from build folder to install destination"
	rm -f $gvm_go_path/pkg.gvm/$package_name/current ||
		display_error "Failed to remove symlink to 'current' before recreating it"
	ln -s $gvm_go_path/pkg.gvm/$package_name/$BUILD_NUMBER $gvm_go_path/pkg.gvm/$package_name/current ||
		display_error "Failed to create new symlink to 'current'"

	if [ -d $build_dir/bin ]; then
		echo " * Installing binaries"
		mkdir -p $gvm_go_path/bin ||
			display_error "Failed to create $gvm_go_path/bin"
		for binary in $build_dir/bin/*; do
			binary_name=`echo "$binary" | awk '{ n=split($1,path,"/"); print path[n] }'`
			rm -f $gvm_go_path/bin/$binary_name ||
				display_error "Failed to remove old binary"

			IFS=$'\n'
			lines=`cat $GVM_ROOT/scripts/templates/binary`
			for line in $lines; do
				echo "$line" | sed 's/{{package_name}}/'$package_name'/g' | sed 's/{{binary_name}}/'$binary_name'/g' >> $gvm_go_path/bin/$binary_name
			done

			chmod +x $gvm_go_path/bin/$binary_name ||
				display_error "Failed to mark binary executable"
		done
	fi
}

function cleanup() {
	rm -rf $tmp_dir ||
		display_error "Failed to remove $tmp_dir in cleanup()"
}

read_command_line $@
download_package
setup_build_env
check_deps
copy_source
build_package
install_package
if [ "$GPKG_PUSH_TAG" == "true" ]; then
	echo "Pushing tag $BUILD_NUMBER"
	cd $WORKSPACE && git tag $BUILD_NUMBER && git push origin $BUILD_NUMBER ||
		display_error "Failed to push version tag"
fi
# TODO: Remove after change to gvm_build
cp $build_dir/manifest $GVM_ROOT/pkgs/pkg.gvm/$package_name/current
cleanup

