#!/usr/bin/env bash
# Make sure the current directory is the location of this script to simplify matters
cd "$(dirname $(readlink -f $0))";
################
### Settings ###
################

# The name of this project
project_name="micro-lanterns";

# The path to the lantern build engine git submodule
lantern_path="./lantern-build-engine";

###
# Custom Settings
###

# Put any custom settings here.
build_output_folder="./dist";

deploy_ssh_user="ci";
deploy_ssh_host="starbeamrainbowlabs.com";
deploy_ssh_port="2403";

###############################################################################

# Check out the lantern git submodule if needed
if [ ! -f "${lantern_path}/lantern.sh" ]; then git submodule update --init "${lantern_path}"; fi

source "${lantern_path}/lantern.sh";

if [[ "$#" -lt 1 ]]; then
	echo -e "${FBLE}${project_name}${RS} build script";
	echo -e "    by Starbeamrainbowlabs";
	echo -e "${LC}Powered by the lantern build engine, v${version}${RS}";
	echo -e "";
	echo -e "${CSECTION}Usage${RS}";
	echo -e "    ./build ${CTOKEN}{action}${RS} ${CTOKEN}{action}${RS} ${CTOKEN}{action}${RS} ...";
	echo -e "";
	echo -e "${CSECTION}Available actions${RS}";
	echo -e "    ${CACTION}setup${RS}            - Perform initial setup";
	echo -e "    ${CACTION}main${RS}             - Build the slide deck";
	echo -e "    ${CACTION}main-watch${RS}       - Build the slide deck automatically when something changes";
	echo -e "    ${CACTION}slides${RS}           - Build the slides HTML";
	echo -e "    ${CACTION}js-css${RS}           - Build the javascript / css";
	echo -e "    ${CACTION}dev-server${RS}       - Start a development server";
	echo -e "    ${CACTION}dev-server-stop${RS}  - Stop the currently running development server";
	echo -e "";
	
	exit 1;
fi

###############################################################################

task_setup() {
	stage_begin "Setting up";
	
	check_command git true;
	check_command node true;
	check_command npm true;
	
	task_begin "Creating build output directory";
	mkdir -p "${build_output_folder}";
	subtask_end $? "Error: Failed to create build output directory at ${HC}${build_output_folder}${RS}";
	
	task_begin "Initialising submodules";
	git submodule update --init;
	task_end $? "Error: Failed to initialise submodules";
	
	task_begin "Installing dependencies";
	npm install;
	task_end $? "Error: Failed to install dependencies";
	
	stage_end 0;
}


# ██████  ███████ ██    ██       ███████ ███████ ██████  ██    ██ ███████ ██████
# ██   ██ ██      ██    ██       ██      ██      ██   ██ ██    ██ ██      ██   ██
# ██   ██ █████   ██    ██ █████ ███████ █████   ██████  ██    ██ █████   ██████
# ██   ██ ██       ██  ██             ██ ██      ██   ██  ██  ██  ██      ██   ██
# ██████  ███████   ████         ███████ ███████ ██   ██   ████   ███████ ██   ██
task_dev-server() {
	task_begin "Starting development server";
	php -S [::1]:50678 -t "${build_output_folder}" &
	exit_code=$?;
	echo $! >/tmp/micro-lantern-dev-server.pid;
	task_end $?; # Should be 0 unless php died for some reason
	sleep 1;
}

task_dev-server-stop() {
	task_begin "Stopping development server";
	
	kill "$(cat /tmp/micro-lantern-dev-server.pid)";
	rm /tmp/micro-lantern-dev-server.pid;
	
	task_end $?;
}

task_main-watch() {
	set_title "Build Watcher";
	
	echo -e "Watching for changes.";
	while :; do # : = infinite loop
		# Wait for an update
		# inotifywait's non-0 exit code forces an exit for some reason :-/
		inotifywait -qr --event modify --format '%:e %f' index.html images css js;
		
		# Rebuild the client code - spawn a sub-process to avoid the hard exit
		# This still doesn't work though, which is *really* annoying
		stage_begin "Rebuilding";
		./build main;
		stage_end 0;
	done
}

task_main() {
	tasks_run js-css;
	
	task_begin "Copying html";
	cp index.html "${build_output_folder}";
	task_end $?;
	
	task_begin "Copying images";
	cp -r images/ "${build_output_folder}";
	task_end $?;
}

task_js-css() {
	task_begin "Packaging Javascript & CSS";
	node_modules/rollup/bin/rollup --sourcemap --config rollup.config.js;
	task_end $? "Error: rollup packing failed!";
}


#  ██████ ██
# ██      ██
# ██      ██
# ██      ██
#  ██████ ██
task_ci() {
	task_begin "Environment Information";
	execute git --version;
	execute node --version;
	execute npm --version;
	task_end $?;
	
	# Run setup in 'development' mode to get the right dependencies installed
	tasks_run setup;
	export NODE_ENV=production;
	# Run the rest in 'production' mode to create a production build
	tasks_run main archive deploy;
}


task_archive() {
	task_begin "Archiving";
	mv "${build_output_folder}" "Linux101/";
	tar cafv "${ARCHIVE}/slides.tar.bz2" "Linux101/";
	exit_code=$?;
	mv "Linux101/" "${build_output_folder}";
	task_end "${exit_code}";
}

task_deploy() {
	task_begin "Deploying to ${deploy_ssh_host}....";
	if [ "${SSH_KEY_PATH}" == "" ]; then
		task_end 1 "Error: Can't find the SSH key as the environment variable SSH_KEY_PATH isn't set.";
	fi
	
	# TODO: If we experience issues, we need to somehow figure out how to recursively delete the contents of the directory before uploading. We may have to install lftp and use that instead
	sftp -i "${SSH_KEY_PATH}" -P "${deploy_ssh_port}" -o PasswordAuthentication=no "${deploy_ssh_user}@${deploy_ssh_host}" << SFTPCOMMANDS
put -r ${build_output_folder}/* Linux101
bye
SFTPCOMMANDS
	
	task_end $?;
}


###############################################################################

tasks_run $@;
