#!/bin/sh

set -e
install_script_version=0.2.1
remote_file="level-darwin-bundle-amd64.pkg"
dl_path="/tmp/$remote_file"
level_binary_path="/usr/local/bin/level"

as_root() {
	if [ "$(id -u)" -eq 0 ]; then
		"$@"
	else
		sudo "$@"
	fi
}

check_sudo() {
	if [ "$(id -u)" -eq 0 ]; then
		return 0
	fi

	if ! sudo -v; then
		printf "\033[31mInstall script requires sudo privileges\033[0m\n"
		exit 1
	fi
}

usage() {
	echo "Usage: $0 [options]"
	echo ""
	echo "Options:"
	echo "  -k, --key   the Level API key"
	echo "  -h, --help  print this help message"
}

# mac os arch detection
get_arch() {
	set +e

	uname -m | grep -q x86_64
	is_x86="$?"

	uname -a | grep -q arm64
	is_arm64="$?"

	uname -m | grep -q 'i.*86'
	is_32bit="$?"

	arch="$(uname -m)"

	set -e

	# account for running under rosetta
	if [ "$is_x86" -eq 0 ]; then
		if [ "$is_arm64" -eq 0 ]; then
			echo 'a64'
		else
			echo 'x64'
		fi
	elif [ "$is_32bit" -eq 0 ]; then
		echo 'x32'
	elif [ "$arch" = "arm64" ]; then
		echo 'a64'
	elif [ "$arch" = "aarch64" ]; then
		echo 'a64'
	else
		printf "\033]31mArchitecture %s not supported\033[0m\n" "$arch"
		exit 1
	fi
}

header() {
	msg=$1
	printf "\033[34m%s\033[0m\n" "$msg"
}

log_msg() {
	msg=$1
	printf "%s\n" "$msg"
}

check_svc_acct() {
	set +e
	as_root $level_binary_path --check-service-account >/dev/null 2>&1
	is_created="$?"
	set -e

	if [ "$is_created" -eq 1 ]; then
		log_msg ""
		header "M1 Support: "
		log_msg "On macOS devices with Apple Silicon, Level uses a service account to ensure that the device can be patched."
		log_msg "This is a limited account that will only be used to install updates."
		log_msg "You can read more about Level's service account here: "
		log_msg ""
		log_msg "https://docs.level.io/en/articles/9926387-macos-service-account"
		log_msg ""
		log_msg ""
		log_msg "The service account will now be created. We're going to ask for your admin username and password."
		log_msg ""

		as_root $level_binary_path --create-service-account
	fi
}

check_sudo

arch=$(get_arch)

# Update remote_file based on architecture
if [ "$arch" = "a64" ]; then
	remote_file="level-darwin-bundle-arm64.pkg"
	dl_path="/tmp/$remote_file"
fi

apikey=
if [ -n "$LEVEL_API_KEY" ]; then
	apikey=$LEVEL_API_KEY
fi

while (("$#")); do
	case "$1" in
	-h | --help)
		usage
		exit 0
		;;
	-k | --key)
		if [ -n "${2:-}" ]; then
			apikey=$2
			shift 2
		else
			printf "\033[31mArgument for '${1}' is missing\033[0m\n"
			exit 1
		fi
		;;
	--dev)
		LEVEL_DEVELOPMENT="true"
		shift 1
		;;
	--latest)
		LEVEL_LATEST="true"
		shift 1
		;;
	--force)
		LEVEL_FORCE_INSTALL="true"
		shift 1
		;;
	-*)
		printf "\033[31mInvalid argument '${1}'\033[0m\n"
		exit 1
		;;
	*)
		break
		;;
	esac
done

if [ "${LEVEL_FORCE_INSTALL:-}" != "true" ]; then
	found=$(as_root launchctl list | grep Level | awk '{print $3}')
	if [ "$found" = "Level" ]; then
		printf "\033[1;33mWARNING: Level service is already installed.\033[0m\n"
		exit
	fi
fi

if [ "${LEVEL_DEVELOPMENT:-}" = "true" ]; then
	printf "\033[1;33mDEVELOPMENT ONLY SCRIPT. IF YOU ARE IN A PRODUCTION ENVIRONMENT PLEASE STOP THIS SCRIPT NOW.\033[0m\n"
fi

base_url=$([ "${LEVEL_DEVELOPMENT:-}" = "true" ] && echo "https://builds.rmm.dev" ||
	echo "https://builds.level.io")
build=$([ "${LEVEL_LATEST:-}" = "true" ] && echo "latest" || echo "stable")
url="$base_url/$build/$remote_file"

if [ ! "$apikey" ]; then
	printf "\033[31mThe Level API key is required.\033[0m\n"
	exit 1
fi

on_error() {
	printf "\033[31m$ERROR_MESSAGE
It looks like you hit an issue when trying to install the Level Agent.
Please send an email to support@level.io or call us at 1-866-42-LEVEL
and we'll do our very best to help you solve your problem.\n\033[0m\n"
}
trap on_error ERR # NOTE: trapping ERR is undefined in posix sh

# Install the agent
printf "\033[34m\n* Downloading Level\n\033[0m"
curl --fail --progress-bar "$url" >"$dl_path"

printf "\033[34m\n* Installing Level, you might be asked for your sudo password...\n\033[0m"
printf "\033[34m\n    - Unpacking and copying files ...\n\033[0m"
as_root installer -pkg "$dl_path" -target /
as_root rm -f "$dl_path"

printf "\033[34m\n    - Starting the agent ...\n\033[0m"

cmd="$level_binary_path -k $apikey -a install"
cmd=("$level_binary_path" -k "$apikey" -a install)
if [ "${LEVEL_LATEST:-}" = "true" ]; then
	cmd+=("--latest")
fi

if [ "${LEVEL_DEVELOPMENT:-}" = "true" ]; then
	cmd+=("--dev")
fi

as_root "${cmd[@]}"

# m1: check if service account is created. It only runs if the interactive mode
# is set.
if [ -t 0 ] && [ "$arch" = "a64" ]; then
	check_svc_acct
fi
