#!/usr/bin/env bash
# Build a local production-style Reasonix desktop package from this checkout.
#
# This is intentionally worktree-relative: run ./prod_test from any clone or
# git worktree and it will package that exact tree, including dirty local changes.
set -euo pipefail

usage() {
	cat <<'EOF'
Usage:
  ./prod_test [platform] [version] [channel]

Examples:
  ./prod_test
  ./prod_test darwin/arm64
  ./prod_test darwin/universal v1.5.0-prodtest stable
  ./prod_fast_test

Defaults:
  platform  auto-detected from this machine; macOS defaults to darwin/universal
  version   v0.0.0-prodtest.<branch-or-detached>.<short-sha>[.dirty]
  channel   stable

Environment overrides:
  PROD_TEST_PLATFORM       Same as first argument.
  PROD_TEST_VERSION        Same as second argument.
  PROD_TEST_CHANNEL        Same as third argument.
  PROD_TEST_FAST           1 enables a faster local iteration build:
                           native host architecture on macOS, no Wails clean,
                           and no DMG packaging unless overridden below.
  PROD_TEST_INSTALL_TOOLS  1 installs missing Wails/create-dmg/nfpm when possible.
                           Set to 0 to only check and print missing deps.
  PROD_TEST_OPEN_DIST      1 opens dist/ after a successful build when supported.
  DESKTOP_BUILD_CLEAN      0 skips Wails -clean.
  DESKTOP_BUILD_SKIP_DMG   1 skips macOS DMG creation.
EOF
}

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
	usage
	exit 0
fi

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

fail() {
	echo "prod_test: $*" >&2
	exit 1
}

need_cmd() {
	command -v "$1" >/dev/null 2>&1 || fail "missing required command: $1"
}

go_bin_dir() {
	local gobin
	gobin="$(go env GOBIN)"
	if [[ -z "$gobin" ]]; then
		gobin="$(go env GOPATH)/bin"
	fi
	printf '%s' "$gobin"
}

sanitize_semver_id() {
	local value="$1"
	value="$(printf '%s' "$value" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^0-9A-Za-z]+/-/g; s/^-+//; s/-+$//; s/-+/-/g')"
	printf '%s' "${value:-local}"
}

detect_platform() {
	local os arch machine
	case "$(uname -s)" in
	Darwin) os="darwin" ;;
	Linux) os="linux" ;;
	MINGW*|MSYS*|CYGWIN*) os="windows" ;;
	*) fail "unsupported host OS: $(uname -s)" ;;
	esac

	machine="$(uname -m)"
	case "$machine" in
	arm64|aarch64) arch="arm64" ;;
	x86_64|amd64) arch="amd64" ;;
	*) fail "unsupported host architecture: $machine" ;;
	esac

	if [[ "$os" == "darwin" ]]; then
		# Match the release workflow's single macOS artifact by default.
		printf 'darwin/universal'
	else
		printf '%s/%s' "$os" "$arch"
	fi
}

detect_native_platform() {
	local os arch machine
	case "$(uname -s)" in
	Darwin) os="darwin" ;;
	Linux) os="linux" ;;
	MINGW*|MSYS*|CYGWIN*) os="windows" ;;
	*) fail "unsupported host OS: $(uname -s)" ;;
	esac

	machine="$(uname -m)"
	case "$machine" in
	arm64|aarch64) arch="arm64" ;;
	x86_64|amd64) arch="amd64" ;;
	*) fail "unsupported host architecture: $machine" ;;
	esac
	printf '%s/%s' "$os" "$arch"
}

default_version() {
	local ref sha dirty
	ref="$(git branch --show-current 2>/dev/null || true)"
	if [[ -z "$ref" ]]; then
		ref="$(git describe --tags --exact-match 2>/dev/null || true)"
	fi
	ref="${ref:-detached}"
	sha="$(git rev-parse --short=8 HEAD 2>/dev/null || echo unknown)"
	dirty=""
	if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
		dirty=".dirty"
	fi
	printf 'v0.0.0-prodtest.%s.%s%s' "$(sanitize_semver_id "$ref")" "$sha" "$dirty"
}

install_or_check_tools() {
	local os install_tools
	os="${1%/*}"
	install_tools="${PROD_TEST_INSTALL_TOOLS:-1}"

	need_cmd git
	need_cmd go
	need_cmd node
	export PATH="$(go_bin_dir):$PATH"

	if ! command -v pnpm >/dev/null 2>&1; then
		if [[ "$install_tools" == "1" ]]; then
			echo "==> installing pnpm"
			if command -v corepack >/dev/null 2>&1; then
				corepack enable
				corepack prepare pnpm@10 --activate
			else
				need_cmd npm
				npm install -g pnpm@10
			fi
		else
			fail "pnpm not found. Install with: corepack enable && corepack prepare pnpm@10 --activate"
		fi
	fi

	if ! command -v wails >/dev/null 2>&1; then
		if [[ "$install_tools" == "1" ]]; then
			echo "==> installing Wails CLI"
			go install github.com/wailsapp/wails/v2/cmd/wails@v2.12.0
		else
			fail "wails not found. Install with: go install github.com/wailsapp/wails/v2/cmd/wails@v2.12.0"
		fi
	fi

	case "$os" in
	darwin)
		if [[ "${DESKTOP_BUILD_SKIP_DMG:-0}" == "1" ]]; then
			return
		fi
		if ! command -v create-dmg >/dev/null 2>&1; then
			if [[ "$install_tools" == "1" && -x "$(command -v brew 2>/dev/null || true)" ]]; then
				echo "==> installing create-dmg"
				brew install create-dmg
			else
				fail "create-dmg not found. Install with: brew install create-dmg"
			fi
		fi
		;;
	linux)
		if ! command -v nfpm >/dev/null 2>&1; then
			if [[ "$install_tools" == "1" ]]; then
				echo "==> installing nfpm"
				go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.46.3
			else
				fail "nfpm not found. Install with: go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.46.3"
			fi
		fi
		;;
	windows)
		command -v makensis >/dev/null 2>&1 || fail "makensis not found. Install NSIS first."
		;;
	esac
}

FAST="${PROD_TEST_FAST:-0}"
if [[ "$FAST" == "1" ]]; then
	export DESKTOP_BUILD_CLEAN="${DESKTOP_BUILD_CLEAN:-0}"
	export DESKTOP_BUILD_SKIP_DMG="${DESKTOP_BUILD_SKIP_DMG:-1}"
fi

if [[ -n "${1:-}" ]]; then
	PLATFORM="$1"
elif [[ -n "${PROD_TEST_PLATFORM:-}" ]]; then
	PLATFORM="$PROD_TEST_PLATFORM"
elif [[ "$FAST" == "1" ]]; then
	PLATFORM="$(detect_native_platform)"
else
	PLATFORM="$(detect_platform)"
fi
VERSION="${2:-${PROD_TEST_VERSION:-$(default_version)}}"
CHANNEL="${3:-${PROD_TEST_CHANNEL:-stable}}"
OPEN_DIST="${PROD_TEST_OPEN_DIST:-1}"

case "$PLATFORM" in
darwin/*|linux/*|windows/*) ;;
*) fail "platform must look like os/arch, got: $PLATFORM" ;;
esac

case "$CHANNEL" in
stable|canary) ;;
*) fail "channel must be stable or canary, got: $CHANNEL" ;;
esac

install_or_check_tools "$PLATFORM"

if [[ -n "$(git status --porcelain)" ]]; then
	echo "==> worktree has uncommitted changes; this build will include them"
	git status --short
fi

wails_json="desktop/wails.json"
tmp_wails="$(mktemp)"
cp "$wails_json" "$tmp_wails"
restore_wails() {
	if [[ -f "$tmp_wails" ]]; then
		cp "$tmp_wails" "$wails_json"
		rm -f "$tmp_wails"
	fi
}
trap restore_wails EXIT

echo "==> root: ."
echo "==> branch: $(git branch --show-current 2>/dev/null || echo detached)"
echo "==> commit: $(git rev-parse --short=8 HEAD 2>/dev/null || echo unknown)"
echo "==> platform: $PLATFORM"
echo "==> version: $VERSION"
echo "==> channel: $CHANNEL"
if [[ "$FAST" == "1" ]]; then
	echo "==> fast mode: DESKTOP_BUILD_CLEAN=$DESKTOP_BUILD_CLEAN DESKTOP_BUILD_SKIP_DMG=$DESKTOP_BUILD_SKIP_DMG"
fi

bash scripts/desktop-build.sh "$PLATFORM" "$VERSION" "$CHANNEL"

echo "==> restored desktop/wails.json"
echo "==> production-style artifacts are in dist/"

if [[ "$OPEN_DIST" == "1" ]]; then
	case "$(uname -s)" in
	Darwin) open dist ;;
	Linux) command -v xdg-open >/dev/null 2>&1 && xdg-open dist >/dev/null 2>&1 || true ;;
	MINGW*|MSYS*|CYGWIN*) explorer.exe dist 2>/dev/null || true ;;
	esac
fi
