#!/bin/bash
set -euo pipefail

REAL_BIN='/usr/share/unity-cli/@BIN_NAME@'

: "${XDG_CONFIG_HOME:=${HOME}/.config}"
: "${XDG_CACHE_HOME:=${HOME}/.cache}"
: "${XDG_DATA_HOME:=${HOME}/.local/share}"

mkdir -p \
	"${XDG_CONFIG_HOME}"/unity \
	"${XDG_CONFIG_HOME}"/unity3d \
	"${XDG_CONFIG_HOME}"/unityhub \
	"${XDG_CACHE_HOME}"/unity \
	"${XDG_CACHE_HOME}"/unityhub \
	"${XDG_DATA_HOME}"/unity3d \
	"${HOME}"/Unity

BWRAP_ARGS=(
	--unshare-all
	--share-net
	--die-with-parent
	--new-session

	# System root & base binaries
	--ro-bind /usr /usr
	--ro-bind /bin /bin
	--ro-bind /lib /lib
	--ro-bind-try /lib64 /lib64
	--ro-bind-try /opt /opt
	--dev /dev
	--proc /proc
	--tmpfs /tmp

	# Fix doctor PATH warning: mount the real binary over the /usr/bin wrapper
	--ro-bind "${REAL_BIN}" '/usr/bin/@BIN_NAME@'

	# Dynamic linker cache & configuration (fixes libgcc_s and stdc++ loading)
	--ro-bind-try /etc/ld.so.cache /etc/ld.so.cache
	--ro-bind-try /etc/ld.so.conf /etc/ld.so.conf
	--ro-bind-try /etc/ld.so.conf.d /etc/ld.so.conf.d
	--ro-bind-try /etc/alternatives /etc/alternatives

	# Network resolution & system identity
	--ro-bind-try /etc/resolv.conf /etc/resolv.conf
	--ro-bind-try /etc/hosts /etc/hosts
	--ro-bind-try /etc/os-release /etc/os-release
	--ro-bind-try /etc/gentoo-release /etc/gentoo-release

	# TLS/SSL certificates
	--ro-bind-try /etc/ssl /etc/ssl
	--ro-bind-try /etc/ca-certificates /etc/ca-certificates
	--ro-bind-try /usr/share/ca-certificates /usr/share/ca-certificates
	--ro-bind-try /etc/pki /etc/pki

	# Sandboxed HOME
	--tmpfs "${HOME}"
	--bind "${XDG_CONFIG_HOME}"/unity "${XDG_CONFIG_HOME}"/unity
	--bind "${XDG_CONFIG_HOME}"/unity3d "${XDG_CONFIG_HOME}"/unity3d
	--bind "${XDG_CONFIG_HOME}"/unityhub "${XDG_CONFIG_HOME}"/unityhub
	--bind "${XDG_CACHE_HOME}"/unity "${XDG_CACHE_HOME}"/unity
	--bind "${XDG_CACHE_HOME}"/unityhub "${XDG_CACHE_HOME}"/unityhub
	--bind "${XDG_DATA_HOME}"/unity3d "${XDG_DATA_HOME}"/unity3d
	--bind "${HOME}"/Unity "${HOME}"/Unity

	# Git & SSH config
	--ro-bind-try "${HOME}"/.gitconfig "${HOME}"/.gitconfig
	--ro-bind-try "${XDG_CONFIG_HOME}"/git "${XDG_CONFIG_HOME}"/git
	--ro-bind-try "${HOME}"/.ssh/known_hosts "${HOME}"/.ssh/known_hosts
	--ro-bind-try "${HOME}"/.ssh/config "${HOME}"/.ssh/config
)

if [ "${PWD}" == "${HOME}" ]; then
	BWRAP_ARGS+=(
		--chdir "${HOME}"
	)
else
	BWRAP_ARGS+=(
		--bind "${PWD}" "${PWD}"
		--chdir "${PWD}"
	)
fi

# Unity Auth Broker sockets (system-wide and per-user)
if [ -S /run/unity-auth-broker/socket ]; then
	BWRAP_ARGS+=( --bind /run/unity-auth-broker/socket /run/unity-auth-broker/socket )
fi

if [ -n "${XDG_RUNTIME_DIR:-}" ] && [ -S "${XDG_RUNTIME_DIR}/unity/auth-broker.sock" ]; then
	BWRAP_ARGS+=( --bind "${XDG_RUNTIME_DIR}/unity/auth-broker.sock" "${XDG_RUNTIME_DIR}/unity/auth-broker.sock" )
fi

# Secret Service / D-Bus session
if [ -n "${DBUS_SESSION_BUS_ADDRESS:-}" ]; then
	case "${DBUS_SESSION_BUS_ADDRESS}" in
		unix:path=*)
			dbus_sock="${DBUS_SESSION_BUS_ADDRESS#unix:path=}"
			dbus_sock="${dbus_sock%%,*}"
			if [ -S "${dbus_sock}" ]; then
				BWRAP_ARGS+=( --bind "${dbus_sock}" "${dbus_sock}" )
			fi
			;;
	esac
elif [ -n "${XDG_RUNTIME_DIR:-}" ] && [ -S "${XDG_RUNTIME_DIR}/bus" ]; then
	BWRAP_ARGS+=( --bind "${XDG_RUNTIME_DIR}/bus" "${XDG_RUNTIME_DIR}/bus" )
fi

# SSH agent forwarding
if [ -n "${SSH_AUTH_SOCK:-}" ] && [ -S "${SSH_AUTH_SOCK}" ]; then
	BWRAP_ARGS+=( --bind "${SSH_AUTH_SOCK}" "${SSH_AUTH_SOCK}" )
fi

# Pass through CLI argument paths if they point to paths outside PWD and HOME
for arg in "$@"; do
	if [ -e "${arg}" ]; then
		real_path=$(realpath "${arg}" 2>/dev/null || true)
		if [ -n "${real_path}" ] && [ "${real_path}" != "${HOME}" ] && [ -e "${real_path}" ]; then
			BWRAP_ARGS+=( --bind-try "${real_path}" "${real_path}" )
		fi
	fi
done

exec bwrap "${BWRAP_ARGS[@]}" -- '/usr/bin/@BIN_NAME@' "$@"
