#!/usr/bin/env bash
# Build a Linux AppImage of OctoLauncher (local or CI).
# Usage: ./scripts/build.sh [--deps]
#   --deps  install native build deps via the distro package manager (needs sudo)
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"

WITH_DEPS=0
for arg in "$@"; do
	case "$arg" in
	--deps) WITH_DEPS=1 ;;
	-h | --help)
		sed -n '2,5p' "$0"
		exit 0
		;;
	*)
		echo "Unknown option: $arg" >&2
		exit 1
		;;
	esac
done

if [[ "$(uname -s)" != "Linux" ]]; then
	echo "This script only builds Linux packages (host is $(uname -s))." >&2
	exit 1
fi

NODE_MAJOR="$(node -p "process.versions.node.split('.')[0]" 2>/dev/null || true)"
if [[ -z "${NODE_MAJOR}" || "${NODE_MAJOR}" -ne 20 ]]; then
	echo "Warning: Node 20 is recommended (found: $(node -v 2>/dev/null || echo none))." >&2
fi

# VS Code / Cursor set this and break Electron.
unset ELECTRON_RUN_AS_NODE
export ELECTRON_RUN_AS_NODE=

is_arch_like() {
	# CachyOS, Arch, EndeavourOS, Manjaro, etc.
	[[ -f /etc/arch-release ]] && return 0
	if [[ -f /etc/os-release ]]; then
		# shellcheck disable=SC1091
		. /etc/os-release
		[[ "${ID:-}" == "arch" || "${ID:-}" == "cachyos" || "${ID_LIKE:-}" == *"arch"* ]] && return 0
	fi
	command -v pacman >/dev/null 2>&1
}

is_debian_like() {
	command -v apt-get >/dev/null 2>&1 || return 1
	if [[ -f /etc/os-release ]]; then
		# shellcheck disable=SC1091
		. /etc/os-release
		[[ "${ID:-}" == "debian" || "${ID:-}" == "ubuntu" || "${ID_LIKE:-}" == *"debian"* ]] && return 0
	fi
	# GitHub ubuntu-latest / other apt hosts without a clear ID_LIKE
	return 0
}

install_deps() {
	if is_arch_like; then
		echo "==> install deps (pacman: base-devel python)"
		sudo pacman -S --needed --noconfirm base-devel python
	elif is_debian_like; then
		echo "==> install deps (apt: build-essential python3)"
		sudo apt-get update
		sudo apt-get install -y build-essential python3
	else
		echo "Unsupported distro for --deps. Install a C++ toolchain + Python 3, then re-run without --deps." >&2
		exit 1
	fi
}

if [[ "${WITH_DEPS}" -eq 1 ]]; then
	install_deps
fi

if ! command -v g++ >/dev/null 2>&1; then
	echo "g++ not found. Install build tools (e.g. ./scripts/build.sh --deps) and retry." >&2
	exit 1
fi

echo "==> npm install (ignore-scripts)"
npm install --ignore-scripts --no-audit --no-fund

# dll-inject is Windows-only (LoadLibrary) and unused in source.
echo "==> drop unused Windows native dep (dll-inject)"
rm -rf node_modules/dll-inject

echo "==> download Electron binary"
node node_modules/electron/install.js

# npm 12+ may no-op `npm rebuild` (install scripts blocked), so build stormlib
# against Electron headers explicitly. Package ships a Windows .node in dist/.
ELECTRON_VERSION="$(node -p "require('./node_modules/electron/package.json').version")"
ELECTRON_ARCH="$(node -p "process.arch")"
echo "==> rebuild stormlib-node for Electron ${ELECTRON_VERSION} (${ELECTRON_ARCH})"
(
	cd node_modules/stormlib-node
	# Don't use post-build.js — it deletes dist/ (wiping enums.js).
	node scripts/pre-configure.js
	npx --yes node-gyp rebuild \
		--target="${ELECTRON_VERSION}" \
		--arch="${ELECTRON_ARCH}" \
		--dist-url=https://electronjs.org/headers
	test -f build/Release/stormlib.node
	cp build/Release/stormlib.node dist/stormlib.node
	rm -rf build
)
file node_modules/stormlib-node/dist/stormlib.node
# Must be ELF on Linux, not the published Windows PE.
if ! file node_modules/stormlib-node/dist/stormlib.node | grep -q ELF; then
	echo "stormlib.node is not a Linux ELF binary after rebuild." >&2
	exit 1
fi
test -f node_modules/stormlib-node/dist/enums.js

echo "==> electron-vite build"
npm run build

echo "==> package AppImage"
npx electron-builder --linux AppImage --config

echo "==> done"
ls -lh distprod/*.AppImage
