#!/usr/bin/make -f
# -*- makefile -*-

# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1

export NODE_PATH=/usr/share/nodejs
export TSHY_NO_INSTALL=1

# All workspaces under src/ — npm-name <-> dirname is intentionally
# computed from package.json at configure time rather than hardcoded.
SRC_WORKSPACES := $(notdir $(wildcard src/*))

MODULE_COMPONENTS := $(patsubst module-%,%,$(notdir $(wildcard module-*)))

# Workspaces built with tshy.
MODULE_BUILDS := \
	clock-mock \
	is-actual-promise \
	processinfo

# Workspaces using plain tsc (with optional tsconfig-esm.json + scripts/fixup.sh).
MODULE_OLD_BUILDS := \
	async-hook-domain \
	function-loop \
	trivial-deferred

# Components present in module-* but NOT installed under /usr/share/nodejs/.
# We keep their source/build (so workspaces that import them resolve at
# build time) but skip the global install to avoid path conflicts with
# other Debian packages.
# - ink: yarnpkg ships /usr/share/nodejs/ink/ at version 4.x
MODULE_SKIP_INSTALL := ink

%:
	dh $@

# We only need to expose src/* workspaces by their npm name (since the
# pkg-js-tools link uses dir name, but tshy resolves by npm name).
override_dh_auto_configure:
	dh_auto_configure --buildsystem=nodejs
	# Drop ink/react/prismjs-terminal-based reporter components.  These
	# pull a huge transitive deptree (ink, react, react-reconciler, yoga,
	# patch-console, etc.) that we cannot build in Debian.
	# Replace src/reporter/src/index.tsx with a slim ESM version exposing
	# only the stream-based reporters (json, junit, markdown) and a
	# pass-through "tap" reporter; remove all .tsx files so tshy doesn't
	# try to compile them.  The default reporter is forced to "tap" in
	# @tapjs/config below.
	rm -f src/reporter/src/*.tsx
	rm -f src/reporter/src/components.ts src/reporter/src/hooks.ts
	rm -rf src/reporter/src/hooks src/reporter/test src/reporter/tap-snapshots

# Workspaces with pre-built dist/ shipped by upstream — used as bootstrap
# to break the @tapjs/core <-> @tapjs/test cycle.  We try to rebuild them
# at the end (REBUILD_BOOTSTRAP target).
SRC_BOOTSTRAP := after core test

# Deterministic build order for the 35 src/* workspaces that have NO
# pre-built dist/.  Ordered topologically so each workspace's @tapjs/*
# deps are built (or pre-built) before it.
SRC_BUILD_ORDER := \
	stack tcompare error-serdes spawn stdin worker typescript tsx \
	esbuild-kit docs npm-init-template yaml \
	parser \
	after-each before before-each chdir filter fixture \
	snapshot asserts sinon clock intercept mock mocha-globals \
	node-serialize nock create-plugin \
	synonyms \
	config \
	reporter \
	dummy-plugin run \
	tap

# Build each workspace with tshy in deterministic order.  Strict: any
# failure aborts the build.
override_dh_auto_build:
	# Older-style modules (tsc + tsc + fixup) — async-hook-domain etc.
	set -e; for d in $(MODULE_OLD_BUILDS); do \
	    echo "=== building (tsc) module $$d ==="; \
	    if [ -f module-$$d/package.json ] && [ ! -d module-$$d/dist ]; then \
	        ( cd module-$$d && \
	          { [ -f tsconfig.json ] && tsc -p tsconfig.json \
	            || { [ -f tsconfig-cjs.json ] && tsc -p tsconfig-cjs.json; }; } && \
	          { [ -f tsconfig-esm.json ] && tsc -p tsconfig-esm.json || true; } && \
	          { [ -f scripts/fixup.sh ] && bash scripts/fixup.sh || true; } \
	        ); \
	    fi; \
	done
	# Build tshy-based module-* components.
	set -e; for d in $(MODULE_BUILDS); do \
	    echo "=== building module $$d ==="; \
	    if [ -f module-$$d/package.json ] && [ ! -d module-$$d/dist ]; then \
	        ( cd module-$$d && tshy ); \
	    fi; \
	done
	# Sanity check: bootstrap dist/ must be present before workspace builds.
	set -e; for d in $(SRC_BOOTSTRAP); do \
	    if [ ! -d src/$$d/dist ]; then \
	        echo "FATAL: src/$$d/dist/ missing (upstream bootstrap was wiped?)" >&2; \
	        exit 1; \
	    fi; \
	done
	[ -d src/test/test-built/dist ] || { \
	    echo "FATAL: src/test/test-built/dist/ missing (upstream bootstrap)" >&2; exit 1; }
	# Build the 35 non-bootstrap workspaces in deterministic order.
	set -e; for d in $(SRC_BUILD_ORDER); do \
	    if [ ! -d src/$$d/src ]; then continue; fi; \
	    if [ -d src/$$d/dist ]; then continue; fi; \
	    if ! grep -q '"tshy"' src/$$d/package.json 2>/dev/null; then continue; fi; \
	    echo "=== building workspace src/$$d ==="; \
	    ( cd src/$$d && tshy ); \
	done
	# Final pass: try to rebuild the bootstrap workspaces from source so we
	# verify we can regenerate what upstream shipped.  Failures are warned
	# but do not abort (we keep the upstream pre-built dist/ in that case).
	# src/test rebuild is more involved (needs test-built regen) so we only
	# try src/after and src/core for now.
	set +e; for d in after core; do \
	    if [ ! -d src/$$d/src ]; then continue; fi; \
	    if ! grep -q '"tshy"' src/$$d/package.json 2>/dev/null; then continue; fi; \
	    echo "=== rebuilding bootstrap workspace src/$$d ==="; \
	    cp -a src/$$d/dist debian/.bootstrap-$$d-dist && \
	    ( cd src/$$d && rm -rf dist && tshy ) ; \
	    if [ ! -d src/$$d/dist ]; then \
	        echo "WARN: rebuild failed for src/$$d, restoring upstream dist/" >&2; \
	        cp -a debian/.bootstrap-$$d-dist src/$$d/dist; \
	    fi; \
	    rm -rf debian/.bootstrap-$$d-dist; \
	done; true

override_dh_auto_test:
	@echo "Tests are run from autopkgtest only"

# Install every built workspace + every module-* component to
# /usr/share/nodejs/<npm-name>/, keeping dist/, package.json and README.
override_dh_auto_install:
	# Run the standard nodejs buildsystem first so dh-nodejs walks
	# debian/nodejs/main + root_modules and populates ${nodejs:Provides}.
	# It tolerates our custom layout because root_modules='*' covers all
	# discovered components.
	dh_auto_install --buildsystem=nodejs
	mkdir -p debian/node-tap/usr/share/nodejs
	# src/ workspaces
	set -e; for d in $(SRC_WORKSPACES); do \
	    name=$$(node -e "console.log(require('./src/'+'$$d'+'/package.json').name)"); \
	    dest=debian/node-tap/usr/share/nodejs/$$name; \
	    case "$$name" in @*/*) mkdir -p debian/node-tap/usr/share/nodejs/$${name%%/*} ;; esac; \
	    mkdir -p $$dest; \
	    cp -a src/$$d/package.json $$dest/; \
	    [ -d src/$$d/dist ] && cp -a src/$$d/dist $$dest/ || true; \
	    [ -f src/$$d/README.md ] && cp -a src/$$d/README.md $$dest/ || true; \
	    [ -f src/$$d/LICENSE.md ] && cp -a src/$$d/LICENSE.md $$dest/ || true; \
	done
	# module-* components
	set -e; for d in $(MODULE_COMPONENTS); do \
	    case " $(MODULE_SKIP_INSTALL) " in *" $$d "*) \
	        echo "skip install of module-$$d (in MODULE_SKIP_INSTALL)"; \
	        continue ;; \
	    esac; \
	    name=$$(node -e "console.log(require('./module-'+'$$d'+'/package.json').name)"); \
	    dest=debian/node-tap/usr/share/nodejs/$$name; \
	    case "$$name" in @*/*) mkdir -p debian/node-tap/usr/share/nodejs/$${name%%/*} ;; esac; \
	    mkdir -p $$dest; \
	    cp -a module-$$d/package.json $$dest/; \
	    [ -d module-$$d/dist ] && cp -a module-$$d/dist $$dest/ || true; \
	    [ -d module-$$d/build ] && cp -a module-$$d/build $$dest/ || true; \
	    [ -d module-$$d/lib ] && cp -a module-$$d/lib $$dest/ || true; \
	    [ -f module-$$d/index.js ] && cp -a module-$$d/index.js $$dest/ || true; \
	    [ -f module-$$d/index.cjs ] && cp -a module-$$d/index.cjs $$dest/ || true; \
	    [ -f module-$$d/index.mjs ] && cp -a module-$$d/index.mjs $$dest/ || true; \
	    [ -f module-$$d/README.md ] && cp -a module-$$d/README.md $$dest/ || true; \
	    [ -f module-$$d/LICENSE.md ] && cp -a module-$$d/LICENSE.md $$dest/ || true; \
	    [ -f module-$$d/LICENSE ] && cp -a module-$$d/LICENSE $$dest/ || true; \
	done

override_dh_fixperms:
	dh_fixperms
	# Make the tap CLI entrypoint executable
	[ ! -f debian/node-tap/usr/share/nodejs/tap/dist/esm/run.mjs ] || \
	    chmod a+x debian/node-tap/usr/share/nodejs/tap/dist/esm/run.mjs

override_dh_installdocs:
	dh_installdocs
