#!/usr/bin/env bash

CYAN='\033[36m'
GREEN='\033[92m'
RED='\033[31m'
YELLOW='\033[33m'
RESET='\033[0m'
UNDERLINE='\033[4m'

LICENSE_DIR="/Users/Shared/Maxon/RLM"
MAXON_APP_DIR="/Applications/Maxon.app/Contents/MacOS/Maxon"
RGS_DIR="/Library/Application Support/Red Giant/Services/Red Giant Service.app/Contents/MacOS/Red Giant Service"
MX1="/Library/Application Support/Maxon/Tools/mx1"

PLUGIN_DIRS=(
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/Trapcode/Shine.plugin/Contents/MacOS/Shine"
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/Trapcode/Particular.plugin/Contents/MacOS/Particular"
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/Red Giant VFX/Primatte6_x64.plugin/Contents/MacOS/Primatte6_x64"
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/Red Giant VFX/OpticalGlow.plugin/Contents/MacOS/OpticalGlow"
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/MB Looks/Looks3_AE10.plugin/Contents/MacOS/Looks3_AE10"
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/Magic Bullet Colorista/Colorista-IV.plugin/Contents/MacOS/Colorista-IV"
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/Maxon Studio/MaxonStudioAE.plugin/Contents/MacOS/MaxonStudioAE"
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/Magic Bullet Bez Friend/ParamCurve.plugin/Contents/MacOS/ParamCurve"
	"/Library/OFX/Plugins/Magic Bullet Suite/Looks3_OFX.ofx.bundle/Contents/MacOS/Looks3_OFX.ofx"
	"/Library/OFX/Plugins/Red Giant VFX/Optiglow.ofx.bundle/Contents/MacOS/Optiglow.ofx"
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/Red Giant Universe/Universe_Utilities_Unmult_Premium_AE_Fx.plugin/Contents/MacOS/Universe_Utilities_Unmult_Premium_AE_Fx"
	"/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/Red Giant Universe/Universe_Glow_Glow_AE_Fx.plugin/Contents/MacOS/Universe_Glow_Glow_AE_Fx"
)

log() {
	echo -e "${CYAN}Log${RESET}: $1"
}

error() {
	echo -e "${RED}Error${RESET}: $1"
}

handle_error() {
	echo -e "${RED}Error${RESET}: Terminal has ${RED}insufficient permissions${RESET}. Exiting."
	echo -e "Give Terminal Full Disk Access: ${UNDERLINE}System Preferences -> Privacy & Security -> Full Disk Access -> Enable Terminal${RESET}"
	exit 1
}

hex() {
	echo "$1" | perl -0777pe 's|([0-9a-zA-Z]{2}+(?![^\(]*\)))|\\x${1}|gs'
}

hex_search() {
	echo "$1" | perl -0777 -ne 'while(/'"$1"'/gs){$count++} END {print $count}' "$2"
}

replace() {
	local dom sub result
	dom=$(hex "$2")
	sub=$(hex "$3")
	result=$(sudo perl -0777pi -e 's|'"$dom"'|'"$sub"'|gs' "$1" 2>&1)
	[[ $result == *"Operation not permitted"* ]] && handle_error
}

prep() {
	sudo xattr -r -d com.apple.quarantine "$1"
	if sudo codesign --force --deep --sign - "$1" 2>/dev/null; then
		echo -e "${GREEN}$(basename "$1")${RESET} patched."
	else
		error "${RED}$(basename "$1")${RESET} failed."
	fi
}

patch() {
	local file="$1"
	if [[ ! -f $file ]]; then
		if [[ $(basename "$file") == "Maxon" || $(basename "$file") == "Red Giant Service" ]]; then
			error "${RED}$(basename "$file")${RESET} not found."
		else
			echo -e "Skipped: ${YELLOW}$(basename "$file")${RESET}, not found."
		fi
		return
	fi

	local patterns expected_patch expected_patched patch_found patched_found
	local patch_count=0
	local patched_count=0

	if [[ $file == "$MAXON_APP_DIR" ]]; then
		patterns=(
			'6D61786F6E2E6E657400' '6D61786F6E2E7A657400'
		)
		expected_patch=6
		expected_patched=6
	elif [[ $file == "$RGS_DIR" ]]; then
		patterns=(
			'7300003428008052A8' '7300003528008052A8'
			'070084DB7407C605' '070084DBEB07C605'
			'015D45FD0020611EE4060054F6FFC039' '015D45FD0020611E37000014F6FFC039'
			'0F57C0660F11014885C00F85F9070000' '0F57C0660F11014885C090E9F9070000'
			'C0000034E80B40B9E90B40F9285900B9BFC31FB80F' '06000014E80B40B9E90B40F9285900B9BFC31FB80F'
			'0F84160000008B45C8488B4DD0894158C745FC00000000E942' 'EB1A160000008B45C8488B4DD0894158C745FC00000000E942'
		)
		expected_patch=6
		expected_patched=6
	else
		patterns=(
			'C0000034E80B40B9E90B40F9285900B9BFC31FB80F' '06000014E80B40B9E90B40F9285900B9BFC31FB80F'
			'0F84160000008B45C8488B4DD0894158C745FC00000000E942' 'EB1A160000008B45C8488B4DD0894158C745FC00000000E942'
		)
		expected_patch=2
		expected_patched=2
	fi

	for ((i = 0; i < ${#patterns[@]}; i += 2)); do
		patch_found="$(hex_search "$(hex "${patterns[i]}")" "$file")"
		[[ $patch_found -ge 1 ]] && ((patch_count += patch_found))
		patched_found="$(hex_search "$(hex "${patterns[i + 1]}")" "$file")"
		[[ $patched_found -ge 1 ]] && ((patched_count += patched_found))
	done

	if [[ $patched_count -ge $expected_patched ]]; then
		echo -e "${YELLOW}$(basename "$file")${RESET} patch already applied."
	elif [[ $patch_count -eq $expected_patch ]]; then
		for ((i = 0; i < ${#patterns[@]}; i += 2)); do
			replace "$file" "${patterns[i]}" "${patterns[i + 1]}"
		done
		prep "$file"
	else
		if [[ $file == *"Maxon"* || $file == *"Service"* ]]; then
			error "${RED}$(basename "$file")${RESET} patching unsuccessful. Ensure the correct version is installed."
		else
			echo -e "${YELLOW}$(basename "$file")${RESET} pattern not found."
		fi
	fi
}

create_license() {
	local license_content
	license_content=$(
		cat <<-EOF
			LICENSE redgiant redgiant 9999.9 permanent uncounted hostid=ANY sig="PUTLERHUYLOLALALALALALALALALALALALALALALALALA"
			LICENSE maxon net.maxon.zbrush 9999.9 permanent uncounted hostid=ANY sig="PUTLERHUYLOLALALALALALALALALALALALALALALALALA"
			LICENSE maxon net.maxon.zbrush.core 9999.9 permanent uncounted hostid=ANY sig="PUTLERHUYLOLALALALALALALALALALALALALALALALALA"
		EOF
	)
	if [[ -f "$LICENSE_DIR/license.lic" ]]; then
		while IFS= read -r line; do
			if ! grep -Fxq "$line" "$LICENSE_DIR/license.lic"; then
				log "${YELLOW}License${RESET} found, unknown if valid."
				return
			fi
		done <<<"$license_content"
		log "License file found and valid."
	else
		[[ ! -d $LICENSE_DIR ]] && sudo mkdir -p "$LICENSE_DIR"
		sudo tee "$LICENSE_DIR/license.lic" >/dev/null <<<"$license_content"
		log "${GREEN}License${RESET} created."
	fi
}

stop_services() {
	log "Killing Maxon."
	killall Maxon 2>/dev/null
	log "Killing Red Giant Service."
	sudo killall "Red Giant Service" 2>/dev/null
	sleep 2
	sudo killall "Red Giant Service" 2>/dev/null
	sleep 2
	sudo killall "Red Giant Service" 2>/dev/null
	sleep 1
}

sudo -u "$(stat -f%Su /dev/console)" "$MX1" user logout 2>/dev/null
stop_services
patch "$MAXON_APP_DIR"
patch "$RGS_DIR"
for plugin_path in "${PLUGIN_DIRS[@]}"; do
	patch "$plugin_path"
done
create_license
