# Maintainer: dispatch
#
# Split package: builds the base application once and produces three packages:
#   dispatch           — application files + CLI wrappers + env configs
#   dispatch-systemd   — systemd system units (run as a given user: dispatch-api@<user>)
#   dispatch-s6        — s6 service definitions for dispatch-api / dispatch-frontend
#
# The Electron desktop wrapper lives in a separate PKGBUILD at packaging/electron/.
#
# Build with:
#   bin/build-pkg                # makepkg -fd in packaging/

pkgbase=dispatch
pkgname=('dispatch' 'dispatch-systemd' 'dispatch-s6')
pkgver=0.0.1
pkgrel=1
arch=('x86_64')
url='https://github.com/anomalyco/dispatch'
license=('MIT')
makedepends=('bun')
# All static files are read directly from ${_projectdir}/packaging/. We don't
# use source=() because two of the s6 files share basenames (run, type), which
# would collide inside ${srcdir}.
source=()
sha256sums=()

_projectdir="${startdir}/.."
_packagingdir="${_projectdir}/packaging"

prepare() {
	mkdir -p "${srcdir}/dispatch-${pkgver}"

	# Copy project files into the src build directory (preserve symlinks)
	cp -a \
		"${_projectdir}/packages" \
		"${_projectdir}/package.json" \
		"${_projectdir}/bun.lock" \
		"${_projectdir}/tsconfig.base.json" \
		"${srcdir}/dispatch-${pkgver}/"

	if [ -f "${_projectdir}/dispatch.toml" ]; then
		cp "${_projectdir}/dispatch.toml" "${srcdir}/dispatch-${pkgver}/"
	fi
}

build() {
	cd "${srcdir}/dispatch-${pkgver}"

	# Install all deps (including devDependencies for vite build)
	bun install --frozen-lockfile

	# Build the frontend with production API port
	VITE_API_URL="${VITE_API_URL:-http://localhost:18390}" \
		bun run --cwd packages/frontend build

	# Slim node_modules for runtime
	rm -rf node_modules
	bun install --frozen-lockfile --production
}

# ----------------------------------------------------------------------------
# dispatch — application files, CLI wrappers, env configs
# ----------------------------------------------------------------------------
package_dispatch() {
	pkgdesc='AI Agent Dispatch — backend + frontend (application files)'
	depends=('bun')
	install=dispatch.install
	backup=(
		'etc/dispatch/dispatch-api.conf'
		'etc/dispatch/dispatch-frontend.conf'
	)

	cd "${srcdir}/dispatch-${pkgver}"

	local optdir="${pkgdir}/opt/dispatch"

	# --- Application files ---

	# API package (full source)
	install -dm755 "${optdir}/packages/api"
	cp -a packages/api/. "${optdir}/packages/api/"

	# Core package (full source)
	install -dm755 "${optdir}/packages/core"
	cp -a packages/core/. "${optdir}/packages/core/"

	# Frontend: built dist + serve script + package.json (for workspace resolution)
	install -dm755 "${optdir}/packages/frontend/dist"
	cp -a packages/frontend/dist/. "${optdir}/packages/frontend/dist/"
	install -Dm644 packages/frontend/serve.ts     "${optdir}/packages/frontend/serve.ts"
	install -Dm644 packages/frontend/package.json "${optdir}/packages/frontend/package.json"

	# Runtime node_modules (preserve symlinks for bun workspaces)
	# Exclude prebuilt ARM64 .node binaries — strip (x86_64 host) can't process them.
	install -dm755 "${optdir}/node_modules"
	cp -a node_modules/. "${optdir}/node_modules/"
	find "${optdir}/node_modules" -path '*/prebuilds/linux-arm64/*.node' -delete

	# Root manifest + lockfile
	install -Dm644 package.json "${optdir}/package.json"
	install -Dm644 bun.lock     "${optdir}/bun.lock"

	# Optional default config
	if [ -f dispatch.toml ]; then
		install -Dm644 dispatch.toml "${optdir}/dispatch.toml"
	fi

	# --- Environment configs (preserved across upgrades via backup=()) ---
	install -Dm644 \
		"${_packagingdir}/dispatch-api.conf" \
		"${pkgdir}/etc/dispatch/dispatch-api.conf"
	install -Dm644 \
		"${_packagingdir}/dispatch-frontend.conf" \
		"${pkgdir}/etc/dispatch/dispatch-frontend.conf"

	# --- CLI wrappers ---
	install -Dm755 \
		"${_packagingdir}/dispatch-api-wrapper.sh" \
		"${pkgdir}/usr/bin/dispatch-api"
	install -Dm755 \
		"${_packagingdir}/dispatch-frontend-wrapper.sh" \
		"${pkgdir}/usr/bin/dispatch-frontend"

	# --- License ---
	if [ -f "${_projectdir}/LICENSE" ]; then
		install -Dm644 "${_projectdir}/LICENSE" \
			"${pkgdir}/usr/share/licenses/dispatch/LICENSE"
	fi
}

# ----------------------------------------------------------------------------
# dispatch-systemd — systemd system unit templates (run as a chosen user)
#
# These are *system* units (managed by PID 1), not user units, so they do not
# depend on a per-user `user@UID.service` manager. Each is a template keyed on
# the username: `dispatch-api@tradam` runs as the `tradam` user via User=%i.
# ----------------------------------------------------------------------------
package_dispatch-systemd() {
	pkgdesc='Systemd system unit templates for the Dispatch API and Frontend services (run as dispatch-api@<user>)'
	depends=("dispatch=${pkgver}" 'systemd')
	conflicts=('dispatch-s6')
	install=dispatch-systemd.install

	install -Dm644 \
		"${_packagingdir}/dispatch-api@.service" \
		"${pkgdir}/usr/lib/systemd/system/dispatch-api@.service"

	install -Dm644 \
		"${_packagingdir}/dispatch-frontend@.service" \
		"${pkgdir}/usr/lib/systemd/system/dispatch-frontend@.service"
}

# ----------------------------------------------------------------------------
# dispatch-s6 — s6 service definitions (for Artix / standalone s6)
# ----------------------------------------------------------------------------
package_dispatch-s6() {
	pkgdesc='s6-rc service definitions for the Dispatch API and Frontend services'
	depends=("dispatch=${pkgver}" 's6' 's6-rc')
	conflicts=('dispatch-systemd')
	install=dispatch-s6.install

	# s6-rc layout: each service is split into a `-srv` (the daemon) and a
	# `-log` (s6-log consumer), linked by producer-for/consumer-for/pipeline-name.
	# The pipeline-name lets `s6-rc -u change dispatch-api` bring both up together.

	# --- dispatch-api-srv ---
	install -Dm755 "${_packagingdir}/s6/dispatch-api-srv/run" \
		"${pkgdir}/etc/s6/sv/dispatch-api-srv/run"
	install -Dm644 "${_packagingdir}/s6/dispatch-api-srv/type" \
		"${pkgdir}/etc/s6/sv/dispatch-api-srv/type"
	install -Dm644 "${_packagingdir}/s6/dispatch-api-srv/producer-for" \
		"${pkgdir}/etc/s6/sv/dispatch-api-srv/producer-for"

	# --- dispatch-api-log ---
	install -Dm755 "${_packagingdir}/s6/dispatch-api-log/run" \
		"${pkgdir}/etc/s6/sv/dispatch-api-log/run"
	install -Dm644 "${_packagingdir}/s6/dispatch-api-log/type" \
		"${pkgdir}/etc/s6/sv/dispatch-api-log/type"
	install -Dm644 "${_packagingdir}/s6/dispatch-api-log/consumer-for" \
		"${pkgdir}/etc/s6/sv/dispatch-api-log/consumer-for"
	install -Dm644 "${_packagingdir}/s6/dispatch-api-log/pipeline-name" \
		"${pkgdir}/etc/s6/sv/dispatch-api-log/pipeline-name"
	# notification-fd must match the `-d3` flag in run; without it s6-log
	# aborts with "invalid notification fd" and the API blocks on a full
	# stdout pipe before it can listen().
	install -Dm644 "${_packagingdir}/s6/dispatch-api-log/notification-fd" \
		"${pkgdir}/etc/s6/sv/dispatch-api-log/notification-fd"

	# --- dispatch-frontend-srv ---
	install -Dm755 "${_packagingdir}/s6/dispatch-frontend-srv/run" \
		"${pkgdir}/etc/s6/sv/dispatch-frontend-srv/run"
	install -Dm644 "${_packagingdir}/s6/dispatch-frontend-srv/type" \
		"${pkgdir}/etc/s6/sv/dispatch-frontend-srv/type"
	install -Dm644 "${_packagingdir}/s6/dispatch-frontend-srv/producer-for" \
		"${pkgdir}/etc/s6/sv/dispatch-frontend-srv/producer-for"

	# --- dispatch-frontend-log ---
	install -Dm755 "${_packagingdir}/s6/dispatch-frontend-log/run" \
		"${pkgdir}/etc/s6/sv/dispatch-frontend-log/run"
	install -Dm644 "${_packagingdir}/s6/dispatch-frontend-log/type" \
		"${pkgdir}/etc/s6/sv/dispatch-frontend-log/type"
	install -Dm644 "${_packagingdir}/s6/dispatch-frontend-log/consumer-for" \
		"${pkgdir}/etc/s6/sv/dispatch-frontend-log/consumer-for"
	install -Dm644 "${_packagingdir}/s6/dispatch-frontend-log/pipeline-name" \
		"${pkgdir}/etc/s6/sv/dispatch-frontend-log/pipeline-name"
	# notification-fd must match the `-d3` flag in run (see dispatch-api-log).
	install -Dm644 "${_packagingdir}/s6/dispatch-frontend-log/notification-fd" \
		"${pkgdir}/etc/s6/sv/dispatch-frontend-log/notification-fd"
}
