#!/usr/bin/make -f

# Debian rules for opencode.
#
# opencode is a Bun-native TypeScript monorepo. There is no Node.js-runnable
# build: the CLI is produced by `bun build --compile` as a self-contained
# binary that embeds the Bun runtime and all JS dependencies. Bun is not
# packaged in Debian, so this build:
#
#   1. downloads the Bun toolchain (pinned to upstream's packageManager
#      version) from the network,
#   2. installs the npm dependencies with `bun install` (pinned by the
#      committed bun.lock), and
#   3. builds the CLI for the build host's architecture only with
#      `bun run script/build.ts --single --skip-install` in packages/cli
#      (upstream 2.x monorepo layout; the web UI is embedded by default).
#
# The Bun toolchain and the npm dependencies are fetched from the network at
# build time: this package REQUIRES a network-enabled build worker and will
# not build on an offline buildd. (Upstream 2.x no longer fetches the
# models.dev catalog at build time; it ships as a committed snapshot in
# packages/core/src/models-dev/snapshot.txt and is refreshed at runtime.)
#
# Build and embed the web UI so the desktop launcher can start `opencode serve`
# (the `web` command was replaced by `serve` in upstream 2.x).
# The terminal TUI and all regular CLI commands remain available through
# /usr/bin/opencode.

export DH_VERBOSE = 1
# sbuild sets HOME=/sbuild-nonexistent (unwritable); bun needs a writable HOME
# (install cache, tmp). Redirect HOME into the build tree.
export HOME := $(CURDIR)/debian/fakehome

# Upstream version and the Bun version upstream requires. Both are derived
# (from the Debian changelog and the root package.json "packageManager"
# field) so a new upstream release no longer needs manual rules edits.
#
# OPENCODE_VERSION must stay set: upstream's build scripts fall back to
# `git branch --show-current` without it, which fails in a build tree
# unpacked from the orig tarball (no .git).
UPSTREAM_VERSION := $(shell dpkg-parsechangelog -SVersion | sed -n 's/-[^-]*$$//p')
BUN_VERSION := $(shell sed -n 's/.*"packageManager": *"bun@\([^"]*\)".*/\1/p' package.json)
ifeq ($(strip $(BUN_VERSION)),)
$(error opencode: cannot read the required Bun version from package.json "packageManager")
endif

# Debian arch -> Bun build target name.
ifeq ($(DEB_HOST_ARCH),amd64)
BUN_TARGET_ARCH := x64
BUN_DL_ARCH := x64
else ifeq ($(DEB_HOST_ARCH),arm64)
BUN_TARGET_ARCH := arm64
BUN_DL_ARCH := aarch64
else
$(error opencode: unsupported DEB_HOST_ARCH $(DEB_HOST_ARCH))
endif

BUN_HOME := $(CURDIR)/debian/.bun-toolchain
BUN := $(BUN_HOME)/bun/bun

# Where the built binary lands. Upstream 2.x builds from packages/cli and
# names the per-target output directory cli-linux-<arch>
# (was opencode-linux-<arch> in the packages/opencode 1.x layout).
DIST_NAME := cli-linux-$(BUN_TARGET_ARCH)
DIST_DIR := packages/cli/dist/$(DIST_NAME)

%:
	dh $@

# ----------------------------------------------------------------------------
# Configure: fetch the Bun toolchain (network).
# ----------------------------------------------------------------------------
override_dh_auto_configure:
	set -e; \
	echo "==> fetching bun $(BUN_VERSION) for linux-$(BUN_DL_ARCH)"; \
	mkdir -p "$(BUN_HOME)"; \
	curl -fSL -o "$(BUN_HOME)/bun.zip" \
		"https://github.com/oven-sh/bun/releases/download/bun-v$(BUN_VERSION)/bun-linux-$(BUN_DL_ARCH).zip"; \
	unzip -q -o "$(BUN_HOME)/bun.zip" -d "$(BUN_HOME)"; \
	mv "$(BUN_HOME)/bun-linux-$(BUN_DL_ARCH)" "$(BUN_HOME)/bun"; \
	rm -f "$(BUN_HOME)/bun.zip"; \
	"$(BUN)" --version

# ----------------------------------------------------------------------------
# Build: install deps and compile the CLI for the build host's arch.
# ----------------------------------------------------------------------------
override_dh_auto_build:
	set -e; \
	mkdir -p $(CURDIR)/debian/fakehome; \
	export PATH="$(BUN_HOME)/bun:$$PATH"; \
	echo "==> bun install --frozen-lockfile (deps pinned by bun.lock; fail"; \
	echo "    loudly if the lockfile ever drifts; lifecycle scripts skipped:"; \
	echo "    native modules ship prebuilt binaries and need no node-gyp)"; \
	bun install --frozen-lockfile --ignore-scripts; \
	echo "==> building $(DIST_NAME) (single target with embedded web UI)"; \
	cd packages/cli; \
	OPENCODE_VERSION=$(UPSTREAM_VERSION) \
		bun run script/build.ts --single --skip-install

# ----------------------------------------------------------------------------
# Test: the staged executable is smoke-tested in the dh_strip sequence
# below. The full upstream test suite needs LLM provider credentials;
# skip it.
# ----------------------------------------------------------------------------
override_dh_auto_test:
	@echo "Skipping upstream test suite (requires LLM provider credentials)."
	@echo "The staged executable is smoke-tested in the dh_strip sequence."

# ----------------------------------------------------------------------------
# Install the compiled binary at a stable, architecture-independent path,
# provide the terminal command, and add separate Web and CLI desktop entries.
# ----------------------------------------------------------------------------
override_dh_auto_install:
	install -D -m 0755 "$(DIST_DIR)/bin/opencode" \
		debian/opencode/usr/lib/opencode/opencode
	install -D -m 0755 debian/opencode-wrapper \
		debian/opencode/usr/bin/opencode
	install -D -m 0644 debian/opencode-web.desktop \
		debian/opencode/usr/share/applications/opencode-web.desktop
	install -D -m 0644 debian/opencode-cli.desktop \
		debian/opencode/usr/share/applications/opencode-cli.desktop
	install -D -m 0644 packages/desktop/icons/prod/icon.png \
		debian/opencode/usr/share/pixmaps/opencode.png

# Bun standalone executables append their compiled module graph to the ELF.
# strip/dwz remove or rewrite that payload, leaving a plain Bun executable.
override_dh_strip:
	@echo "Skipping dh_strip: it corrupts Bun standalone executables."
	env -u BUN_BE_BUN debian/opencode/usr/lib/opencode/opencode --version

override_dh_dwz:
	@echo "Skipping dh_dwz: it is unsafe for Bun standalone executables."

# ----------------------------------------------------------------------------
# Clean.
# ----------------------------------------------------------------------------
override_dh_auto_clean:
	rm -rf "$(BUN_HOME)" node_modules packages/cli/dist packages/app/dist debian/fakehome
	dh_auto_clean
