#!/usr/bin/env zsh
# vi: set ft=zsh tw=80 ts=2

function getExecPrerequisites() {
	cmds+=(
		[launchctl]=''
		[git]=''
		[mkdir]=''
		[chmod]=''
		[]=''
	)
}

function hideFolders() {
	chflags hidden ${HOME}/bin
}

function checkExecPrerequisites() {
	local -A cmds
	getExecPrerequisites || return
	checkCommands -m 'This script needs %1$s to work. Please install and retry.' ${(k)cmds} || return
}

function configureInstallPrefix() {
	local dirPath= desc=
	for dirPath desc in ${homebrew_prefix} 'Creating install prefix' ${homebrew_directory} 'Creating Homebrew directory'; do
		if [[ ! -d ${dirPath} ]]; then
			indicateActivity -- ${desc} createDirAndLogOnFailure ${dirPath}
		fi
	done
}

function createDirAndLogOnFailure() {
	local dirPath=$1
	mkdir -p ${dirPath} 2> /dev/null || {
		loptty -- -e 'Could not create directory' -e $dirPath
		return 10
	}
	chmod 744 ${dirPath}
}

function downloadHomebrew() {
	local git_homebrew_remote=`getDefaultGitHomebrewURL`
	pushd -q ${homebrew_directory} || return 10
	test -d ".git" && return
	git init -q
	git config remote.origin.url "${git_homebrew_remote}"
	git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
	git config core.autocrlf false
	git config --replace-all homebrew.analyticsmessage false
	git config --replace-all homebrew.caskanalyticsmessage false
	git fetch --quiet --force origin > /dev/null
	git fetch --quiet --force --tags origin > /dev/null
	git reset --hard origin/master
	popd -q
}

function getCanonicalBrewPath() {
	local brewPath=${homebrew_directory}/bin/brew
	if [[ $brewPath == $HOME* ]]; then
		brewPath="\${HOME}${brewPath#$HOME}"
	fi
	echo $brewPath
}

function createBrewCallerScript() {
	local cmdPath=${HOME}/bin/brew
	local brewPath=`getCanonicalBrewPath`
	[[ -f ${cmdPath} ]] && rm ${cmdPath}
	mkdir -p ${cmdPath:h}
	cat <<- BREWCALLER > ${cmdPath}
	#!/usr/bin/env zsh
	export HOMEBREW_CASK_OPTS="--no-quarantine \${HOMEBREW_CASK_OPTS}"
	export HOMEBREW_NO_AUTO_UPDATE=1
	export HOMEBREW_NO_ANALYTICS=1
	export HOMEBREW_NO_ANALYTICS_THIS_RUN=1
	export HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT=1
	"${brewPath}" "\$@"
	BREWCALLER
	chown $(id -un):$(id -gn) ${cmdPath}
	chmod u=rwx,go=r ${cmdPath}
}

function createBrewPeriodicScript() {
	local brewPath=`getCanonicalBrewPath`
	local cmdPath=${HOME}/bin/brew-periodic
	[[ -f ${cmdPath} ]] && rm ${cmdPath}
	mkdir -p ${cmdPath:h}
	cat <<- BREWCALLER > ${cmdPath}
	#!/usr/bin/env zsh
	local brew='${brewPath}'
	\$brew update
	\$brew upgrade --greedy
	\$brew cleanup
	BREWCALLER
	chown $(id -un):$(id -gn) ${cmdPath}
	chmod u=rwx,go=r ${cmdPath}
}

function updateBrew() {
	local brewPath=${homebrew_directory}/bin/brew
	${brewPath} update --force --quiet
	chmod go-w "${homebrew_directory}/share/zsh"
}

function createLaunchDaemonsPlist() {
	local uid=`id -u`
	local serviceName="de.astzweig.macos.launchagents.$1"
	local launchAgentPath=${HOME}/Library/LaunchAgents
	local launcherPath="${launchAgentPath}/${serviceName}.plist"
	[[ -d ${launchAgentPath} ]] || mkdir ${launchAgentPath} || return
	[[ -f ${launcherPath} ]] && {
		launchctl disable gui/${uid}/${serviceName}
		rm ${launcherPath}
	}
	cat <<- LAUNCHDPLIST > ${launcherPath}
	<?xml version="1.0" encoding="UTF-8"?>
	<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
	<plist version="1.0">
		<dict>
			<key>Label</key>
			<string>${serviceName}</string>
			<key>ProgramArguments</key>
			<array>
				<string>${HOME}/bin/brew-periodic</string>
			</array>
			<key>StartInterval</key>
			<integer>1800</integer>
		</dict>
	</plist>
	LAUNCHDPLIST
	chmod u=rw,go=r ${launcherPath}
	launchctl enable gui/${uid}/${serviceName} &> /dev/null
	launchctl bootstrap gui/${uid}/ ${launcherPath} &> /dev/null || true
}

function installHomebrewUpdater() {
	createLaunchDaemonsPlist brew-updater
}

function getDefaultHomebrewPrefix() {
	print -- ${HOMEBREW_PREFIX:-${HOME}/Library/Application Support}
}

function getHomebrewDirectoryPath() {
	print -- ${homebrew_prefix:-$(getDefaultHomebrewPrefix)}/Homebrew
}

function getDefaultGitHomebrewURL() {
	print -- ${HOMEBREW_BREW_GIT_REMOTE:-https://github.com/Homebrew/brew.git}
}

function configureFolders() {
	local dirPath
	for dirPath in ${HOME}/bin ${HOME}/.vim/{backups,swaps}; do
		[[ ! -d ${dirPath} ]] && indicateActivity -- "Creating ${dirPath}" mkdir ${dirPath}
	done
	indicateActivity -- 'Hide folders' hideFolders
}

function installNode() {
	volta install node
}

function main() {
	lop -y h1 -- -i 'Setup User'
	[[ $(id -u) -eq 0 ]] && { loptty -- -e 'Command must not be run as root.' -e $dirPath; return 16  }
	configureFolders
	indicateActivity -- 'Install node' installNode
	local homebrew_prefix=`getDefaultHomebrewPrefix`
	local homebrew_directory=`getHomebrewDirectoryPath`
	checkExecPrerequisites || return 17
	configureInstallPrefix || return 10
	indicateActivity -- 'Downloading Homebrew' downloadHomebrew || return 11
	indicateActivity -- 'Create brew caller script' createBrewCallerScript || return 12
	indicateActivity -- 'Create brew periodic script' createBrewPeriodicScript || return 13
	indicateActivity -- 'Update brew' updateBrew || return 14
	indicateActivity -- 'Install Homebrew updater' installHomebrewUpdater || return 15
}

if [[ "${ZSH_EVAL_CONTEXT}" == toplevel || "${ZSH_EVAL_CONTEXT}" == cmdarg ]]; then
	_DIR="${0:A:h}"
	source autoload-zshlib
	main "$@"
fi
