#!/bin/zsh

#
# rnt() = RentDynamics God Function
#
# Performs one of the following actions based on first argument:
# 	- (arg = NO ARGUMENT)  Deactivate current virtual environment and return to $RD_PATH
# 	- (arg = project-name) Activate (and step into) project by name
# 	- (arg = 'db')         Connect to databases available to the 1-password api
# 	- (arg = 'op')         1pass login/logout tool for current shell (assists in quick db access)
# 	- (arg = 'refresh_db') Drops and recreates local POSTGRES databases
# 	- (arg = 'cleanup')    Performs safe-deletions on all projects' inactive branches
# 	- (arg = 'status')     Uses 'rockymadden/slack-cli' to update slack status
# 	- (arg = 'mail')       BROKEN : Uses a VMAIL client to connect to email
#
# The (arg = project-name) case requires the following project file-structure:
#	$RD_PATH/project-name
#	  | /code (created by git clone PROJECT_URL code)
#	  | /env  (created by virtualenv or nodeenv)
#	

function rnt() {
	ERROR_CODE=0;

	case $1 in
		db | DB)
			RENT_DYNAMICS_CONNECT_TO_DATABASE "${@:2}" || ERROR_CODE=1;
			;;
		refresh_db | REFRESH_DB)
			RENT_DYNAMICS_REFRESH_LOCAL_POSTGRES_DATABASES "${@:2}" || ERROR_CODE=2;
			;;
		cleanup | CLEANUP)
			RENT_DYNAMICS_GIT_PROJECT_CLEAN_UP "${@:2}" || ERROR_CODE=3;
			;;
		status | slack-status)
			RENT_DYNAMICS_UPDATE_SLACK_STATUS "${@:2}" || ERROR_CODE=4;
			;;
		mail | MAIL | email | EMAIL)
			RENT_DYNAMICS_CONNECT_TO_EMAIL || ERROR_CODE=5;
			;;
		op | 1pass )
			RENT_DYNAMICS_ONE_PASSWORD "${@:2}" || ERROR_CODE=6;
			;;
		clone )
			RENT_DYNAMICS_GIT_PROJECT_SET_UP "${@:2}" || ERROR_CODE=7;
			;;
		shell )
			RENT_DYNAMICS_MANAGE_PY_SHELL "${@:2}" || ERROR_CODE=8;
			;;
		usage )
			RENT_DYNAMICS_CHECK_PROJECT_USAGE "${@:2}" || ERROR_CODE=9;
			;;
		*)
			deactivate >/dev/null 2>/dev/null || deactivate_node >/dev/null 2>/dev/null;
			cd "$RD_PATH"
			source "$RD_PATH/ENV.sh"

			[ -d "$1" ] && {
				cd "$1" >/dev/null 2>/dev/null;
				[ -f "./env/bin/activate" ] \
					&& source "./env/bin/activate" \
					|| echo 'No environment here, boss!';
				[ -f "./myenv" ] \
					&& source "./myenv" \
					&& echo 'Loaded custom environment settings!';
				[ -d "./code" ] && cd "./code";
			}
	esac

	return ERROR_CODE;
}
_rnt () { # autocompletion
	local state;

	_arguments \
		'1: :->project_or_command'\
		':: :->command_args'\
		;
	case "$state" in
		project_or_command)
			compadd $(ls "$RD_PATH");
			compadd db refresh_db cleanup mail status op clone usage;
			;;
		command_args)
			[ $words[2] == 'status' ] && _RENT_DYNAMICS_UPDATE_SLACK_STATUS;
			[ $words[2] == 'op' ] && _RENT_DYNAMICS_ONE_PASSWORD;
			;;
	esac
}
compdef _rnt rnt;

###############################################################################
### HELPERS ###################################################################
###############################################################################

function RENT_DYNAMICS_CONNECT_TO_DATABASE() {
	"$DOTWRYN/bin/rentdynamics/db.sh" "$@";
}

function RENT_DYNAMICS_REFRESH_LOCAL_POSTGRES_DATABASES() {
	psql -U postgres -c "DROP DATABASE rentdynamics;"
	psql -U postgres -c "CREATE DATABASE rentdynamics with owner rd;"
	psql -U postgres -c "DROP DATABASE rdrentplus;"
	psql -U postgres -c "CREATE DATABASE rdrentplus with owner rd;"
}

function RENT_DYNAMICS_GIT_PROJECT_CLEAN_UP() {
	printf "\nInitializing branch cleanup...\n\n"
	for dir in $(ls $RD_PATH); do
		rnt $dir >/dev/null 2>/dev/null;
		if [ -d .git ]; then
			printf " - %s\e[1;34m %s\e[0m..." "clearing repository" "$dir";
			git branch -d $(git branch | sed -E "/master|\*|epic-*/d") >/dev/null 2>/dev/null;
			printf "\e[1;32m%s\e[0m\n" " DONE";
		else
			printf " - \e[1;34m%s\e[1;31m %s\e[0m\n" "$dir" "is not a git repository";
		fi
		rnt;
	done;
	printf "\n\n\e[1;36m%s\e[1;35m %s\e[0m\n\n" "RentDynamics" "repository branches all clean!";
}

function RENT_DYNAMICS_CONNECT_TO_EMAIL() {
	xdg-open https://mail.google.com/mail/u/1;
}

function RENT_DYNAMICS_UPDATE_SLACK_STATUS() {
	slack-cli --version >/dev/null 2>&1 || {
		echo 'I require the slack-cli. For installation and setup, see https://github.com/rockymadden/slack-cli';
	}
	ERROR_MESSAGE="Slack CLI Error"

	local STATUS_ARG;
	case $1 in
		start)
			STATUS_ARG='boost';
			;;
		stop)
			STATUS_ARG='ride';
			;;
		*)
			STATUS_ARG="$1";
			;;
	esac

	local ACTIVE='active';
	local AWAY='away';
	local PRESENCE="$ACTIVE";

	local MESSAGE;
	local EMOJI;
	case $STATUS_ARG in
		boost | boost-fire | f-zero)
			MESSAGE="Use your heart, and boost fire!"; EMOJI=':boost_fire:';
			;;
		monkas)
			MESSAGE=" "; EMOJI=':monkas:';
			;;
		ride | bike-ride | bike)
			MESSAGE="probably riding"; EMOJI=':man-biking:'; PRESENCE="$AWAY";
			;;
		plank)
			MESSAGE="plank time!"; EMOJI=':evergreen_tree:';
			;;
		meal | eat | food)
			MESSAGE="so hungry..."; EMOJI=':hamburger:'; PRESENCE="$AWAY";
			;;
		turbo)
			MESSAGE="ZOOOM"; EMOJI=':turbo:';
			;;
		super)
			MESSAGE="AAAAAAAAAAAAHHHHHHHHH"; EMOJI=':gohan:';
			;;
		meeting)
			MESSAGE="afk"; EMOJI=':necktie:'; PRESENCE="$AWAY";
			;;
		budget)
			MESSAGE="did somebody say skee-ball??"; EMOJI=':scales:';
			;;
		cheese)
			MESSAGE="only the most important things on my mind"; EMOJI=':cheese_wedge:';
			;;
		foos)
			MESSAGE="I will defeat Mike... someday..."; EMOJI=':soccer:'; PRESENCE="$AWAY";
			;;
		lax | belax | belax8 )
			MESSAGE="BELAAAAAAAX"; EMOJI=':exploding_head:';
			;;
		panic)
			MESSAGE="dont panic!"; EMOJI=':exclamation:';
			;;
		off | not-working | no-money)
			MESSAGE="not making money"; EMOJI=':sunglasses:'; PRESENCE="$AWAY";
			;;
		school )
			MESSAGE="Shhhh! Taking notes..."; EMOJI=':male-teacher:'; PRESENCE="$AWAY";
			;;
		clear | clear-status | no-status | please-turn-off-my-status-mr-slack-robot)
			slack status clear >/dev/null 2>&1
			;;
		:*:)
			MESSAGE=" "; EMOJI="$1";
			;;
		*)
			ERROR_MESSAGE="Unrecognized preset or emoji";
			;;
	esac

	[ $2 ] && MESSAGE="$2";

	[ $EMOJI ] \
		&& slack-cli status edit "$MESSAGE" "$EMOJI" >/dev/null 2>&1 \
		&& slack-cli presence $PRESENCE >/dev/null 2>&1 \
		&& echo "Slack status successfully updated! : ($STATUS_ARG)" \
		|| echo "ERROR:::Failed to update slack status :c ($ERROR_MESSAGE)";
}
_RENT_DYNAMICS_UPDATE_SLACK_STATUS() { # autocompletion
	compadd \
		boost-fire bike-ride monkas surprised plank meal turbo super meeting budget cheese foos belax \
		panic not-working school clear-status \
		;
}

RENT_DYNAMICS_ONE_PASSWORD() {
	ERROR_CODE=0;

	case $1 in
		login )
			RENT_DYNAMICS_ONE_PASSWORD_LOGIN "${@:2}" || ERROR_CODE=1;
			;;
		logout | deactivate )
			RENT_DYNAMICS_ONE_PASSWORD_LOGOUT "${@:2}" || ERROR_CODE=2;
			;;
		* )
			RENT_DYNAMICS_ONE_PASSWORD_CHECK_LOGIN "${@:2}" || ERROR_CODE=3;
			;;
	esac

	return "$ERROR_CODE";
}
_RENT_DYNAMICS_ONE_PASSWORD() { # autocompletion
	compadd \
		login deactivate\
		;
}

RENT_DYNAMICS_ONE_PASSWORD_LOGIN() {
	ERROR_CODE=0;

	RENT_DYNAMICS_ONE_PASSWORD_IS_LOGGED_IN && {
		echo 'Already logged in!';
	} || {
		unset OP_SESSION_rent_dynamics;
		eval $(op signin rent_dynamics 2>/dev/null);

		op list templates >/dev/null 2>&1 && {
			echo 'Successfully logged in to 1-password!';
		} || {
			echo 'Failed to log in. Double check your password and op-cli settings.';
			echo 'Have you run one-time setup? (`op signin rent-dynamics.1-password.com <your-email-address>`)';
			ERROR_CODE=1;
		};
	}

	return "$ERROR_CODE";
}

RENT_DYNAMICS_ONE_PASSWORD_LOGOUT() {
	[ ! -z $OP_SESSION_rent_dynamics ] && {
		unset OP_SESSION_rent_dynamics && echo 'Successfully logged out from 1-password';
	} || {
		echo 'Current shell is not logged in to 1-password';
		return 1;
	}
}

RENT_DYNAMICS_ONE_PASSWORD_CHECK_LOGIN() {
	RENT_DYNAMICS_ONE_PASSWORD_IS_LOGGED_IN \
		&& echo 'Current shell is logged-in to rent_dynamics 1-password'\
		|| echo 'Current shell is not logged-in rent_dynamics 1-password';
	return 0;
}

RENT_DYNAMICS_ONE_PASSWORD_IS_LOGGED_IN() {
	op list templates >/dev/null 2>&1 && return 0 || return 1;
}

RENT_DYNAMICS_GIT_PROJECT_SET_UP() {
	PROJECT_URL="git@github.com:RentDynamics/$1.git";
	PROJECT_DIR="$RD_PATH/$1";

	[ -d "$PROJECT_DIR" ] \
		&& { echo "Project '$1' already exists locally (access quickly with 'rnt $1')."; return 1; }

	git ls-remote "$PROJECT_URL" >/dev/null || return 2;

	mkdir "$PROJECT_DIR" >/dev/null 2>&1;
	git clone -q "$PROJECT_URL" "$PROJECT_DIR/code" \
		&& echo "Succesfully cloned project '$1' (access quickly with 'rnt $1')." \
		|| { echo "$PROJECT_DIR"; rm -rI "$PROJECT_DIR" }
}

RENT_DYNAMICS_MANAGE_PY_SHELL() {
	echo 'TODO: Implement me!';
	return;

	MANAGE_PY_DIR="$(pwd | sed 's/\(.*code\).*/\1/')";
	PROJECT_NAME="$(pwd | sed 's/.*\/\(.*\)\/code.*/\1/' | sed 's/-/_/g')";

	IMPORT_MODELS="from $PROJECT_NAME.domain.models import *\n";
	IMPORT_HELPER="from $PROJECT_NAME.test.helpers import *\n";

	IMPORT_PPRINT='from pprint import pprint\n';
	PPRINT_LAMBDA='P = lambda x: pprint(vars(x))\n';

	COMMANDS="$IMPORT_MODELS$IMPORT_HELPER$IMPORT_PPRINT$PPRINT_LAMBDA";

	"$MANAGE_PY_DIR/manage.py" shell -i ipython <(echo $COMMANDS);
}

RENT_DYNAMICS_CHECK_PROJECT_USAGE() {
	echo "The regex $1 is found in the following projects/repositories:\n"
	rg $1 $RD_PATH -l | sed 's/^.*w0ryn\/RentDynamics\///' | sed 's/\/.*$//' | sort | uniq;
	echo;
}