# musiquay - the web app: wasm bundles + static shell for the musiquay platform.
#
# The native relay lives in ../morly; it serves this directory. `make build`
# leaves a deployable web/static/ (boot, sign-in, wallet, settings) - the
# kind-1 forum is parked and the MLS/Marmot DM worker is parked (see below).

MOXIE    ?= $(CURDIR)/../moxie/moxie
# An inherited MOXIEROOT is ignored on purpose: `?=` cannot tell an exported
# stale root from an intended one, and a stale root silently compiles a
# different tree's src/ and pkg/. Pass it on the command line to build against
# another tree: make MOXIEROOT=/path/to/moxie ...
ifeq ($(origin MOXIEROOT),environment)
MOXIEROOT := $(CURDIR)/../moxie
endif
MOXIEROOT ?= $(CURDIR)/../moxie

# Moxie closures do not capture: a closure receives what it needs through its
# parameters. The app predates that enforcement and registers hundreds of
# handlers that close over the enclosing frame, so every build opts out
# explicitly (same as smesh; porting them is app work, not a compiler change).
CAPTURES ?= -allow-closure-captures

# The relay used by the smoke test. It lives in ../morly and is built there.
MORLY    ?= $(CURDIR)/../morly/morly

# === Frontend (WASM) ===
build-app-wasm:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/app.wasm ./web/wasm/app/

build-relay-proxy-wasm:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/relay-proxy.wasm ./web/wasm/relay-proxy/

build-store-wasm:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/store.wasm ./web/wasm/store/

build-verify-wasm:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/verify.wasm ./web/wasm/verify/

build-profile-wasm:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/profile.wasm ./web/wasm/profile/

build-notif-wasm:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/notif.wasm ./web/wasm/notif/

build-sw:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/\$$sw/sw.wasm ./web/wasm/sw/

# The signer is a page-embedded worker; no browser extension is required.
build-signer:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/signer.wasm ./web/wasm/signer/

# Parked modules. Neither is built or served by default:
#   * feed - the kind-1 forum feed worker; every forum route lands on the empty
#            home page and nothing subscribes to kind 1 (see web/wasm/app/main.mx).
#   * mls  - the MLS/Marmot DM worker; it panics in Moxie's codec generating its
#            first KeyPackage (an invalid type descriptor), parked until fixed.
build-feed-wasm:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/feed.wasm ./web/wasm/feed/

build-mls-wasm:
	MOXIEROOT=$(MOXIEROOT) GOWORK=off $(MOXIE) build $(CAPTURES) -target wasm -o $(CURDIR)/web/static/mls.wasm ./web/wasm/mls/

# === All ===
build: build-app-wasm build-relay-proxy-wasm build-store-wasm build-verify-wasm build-profile-wasm build-notif-wasm build-signer build-sw

# === Dev (frontend only, relay already running) ===
dev: build-app-wasm build-relay-proxy-wasm build-store-wasm build-verify-wasm build-profile-wasm build-notif-wasm build-sw

# === Test ===
# Every package under pkg/ and web/ carrying a *_test.mx, through the compiler's
# harness. pkg/protocol is the vocabulary every other package is written
# against, so its tests are part of the gate, not an extra.
UNIT_SKIP ?=
test-unit:
	@set -e ; for d in $$( find pkg web -name '*_test.mx' | xargs -n1 dirname | sort -u ) ; do \
		case " $(UNIT_SKIP) " in *" $$d "*) echo "=== unit: $$d (skipped)" ; continue ;; esac ; \
		echo "=== unit: $$d" ; \
		MOXIEROOT=$(MOXIEROOT) $(MOXIE) test $(CAPTURES) ./$$d || exit 1 ; \
	done

# Standalone vector harnesses under web/_test/ (each is a main package that
# prints its own pass/fail count and exits non-zero on failure).
test-helpers:
	@set -e ; for d in web/_test/bech32test web/_test/hkdftest ; do \
		b=$$(basename $$d) ; \
		echo "=== harness: $$d" ; \
		MOXIEROOT=$(MOXIEROOT) $(MOXIE) build $(CAPTURES) -o $(CURDIR)/tmp/$$b ./$$d ; \
		$(CURDIR)/tmp/$$b ; \
	done

# The harness verifies the signer's signatures against the legacy moxiejs
# secp256k1 runtime - an independent implementation, and a build product of the
# legacy compiler rather than part of this tree. It looks in the smesh checkout
# by default; override with MOXIEJS_RUNTIME=/path/to/signer-bg/$runtime. The
# harness names that path when it is missing.
test-signer: build-signer
	node web/_test/signertest/run.mjs web/static/signer.wasm

# Playwright smoke test: boots the morly relay against this static dir, loads
# the app, signs in and asserts the parked state (no forum UI, empty main area
# and notifications). Build the relay first: cd ../morly && make build
test-smoke:
	MORLY=$(MORLY) python3 -m pytest test -v --tb=short

test: test-unit test-helpers test-signer test-smoke

.PHONY: build-app-wasm build-relay-proxy-wasm build-store-wasm build-verify-wasm build-profile-wasm build-notif-wasm build-feed-wasm build-mls-wasm build-sw build-signer build dev test-unit test-helpers test-signer test-smoke test
