# jsqlite -- a SQLite3-compatible database engine in Jerboa Scheme.
#
# jerbuild bundles Chez Scheme + the jerboa stdlib, so building jsqlite needs
# only `jerbuild` on PATH. This vendored copy keeps only self-contained
# production, unit, and robustness targets.

JERBUILD ?= jerbuild
JH := $(shell $(JERBUILD) --jerboa-home 2>/dev/null)
ifeq ($(JH),)
$(error jerbuild not found on PATH (or '$(JERBUILD) --jerboa-home' failed). Install jerbuild, or set JERBUILD=/path/to/jerbuild)
endif

SRC_DIR   := $(CURDIR)/src
TOOLS_DIR := $(CURDIR)/tools

# Production execution: just our source + the jerboa stdlib.
LIBDIRS      := $(SRC_DIR):$(JH)/lib

UNIT_TESTS := $(wildcard tests/unit/*.ss)

.PHONY: all build unit test corrupt concurrency cshim robustness clean help
.DEFAULT_GOAL := help

all: test

# Compile-check: import every production module (R6RS libraries in .ss files
# are consumed directly via libdirs, so there is no transpile step).
build:
	$(JERBUILD) exec --libdirs "$(LIBDIRS)" tools/build-check.ss

# Unit tests run directly against src/ (jerbuild exec compiles on the fly).
unit:
	@fail=0; for t in $(UNIT_TESTS); do \
	  echo "== unit: $$t =="; \
	  $(JERBUILD) exec --libdirs "$(LIBDIRS)" $$t || fail=1; \
	done; \
	if [ $$fail -ne 0 ]; then echo "UNIT FAILURES"; exit 1; fi

test: unit

# Malformed-image corpus test.
corrupt:
	$(JERBUILD) exec --libdirs "$(LIBDIRS)" tools/corrupt-test.ss $(N) $(SEED)

# Multi-process write-locking stress test: 4 processes hammer one file, then
# verify no writes were lost. Needs only jsqlite (no oracle). `make concurrency N=40`.
concurrency:
	@P=/tmp/jsqlite-concurrency.db; n=$${N:-40}; \
	for mode in "" wal; do \
	  echo "== concurrency (journal mode: $${mode:-rollback}) =="; \
	  rm -f $$P $$P-lock $$P-journal $$P-wal $$P-shm; \
	  $(JERBUILD) exec --libdirs "$(LIBDIRS)" tools/concurrency-test.ss init $$P; \
	  for id in 1 2 3 4; do \
	    $(JERBUILD) exec --libdirs "$(LIBDIRS)" tools/concurrency-test.ss worker $$id $$n $$P $$mode >/dev/null & \
	  done; wait; \
	  $(JERBUILD) exec --libdirs "$(LIBDIRS)" tools/concurrency-test.ss verify $$P 4 $$n || exit 1; \
	done

# Write-path / B-tree property test vs the oracle (`make dmlfuzz N=2000 SEED=7`).
dmlfuzz:
	@if [ ! -d "$(REF_DIR)" ]; then echo "SKIP dmlfuzz: reference $(REF_DIR) not found"; exit 0; fi; \
	$(MAKE) --no-print-directory -C $(REF_DIR) build >/dev/null || \
	  { echo "SKIP dmlfuzz: reference build failed"; exit 0; }; \
	DYLD_LIBRARY_PATH=$(REF_DIR) LD_LIBRARY_PATH=$(REF_DIR) \
	$(JERBUILD) exec --libdirs "$(DIFF_LIBDIRS)" tools/dml-fuzz.ss $(N) $(SEED)

# C ABI shim: compile the C driver (shim/driver.c) and have it drive jsqlite
# prepared statements through the jsq_api function-pointer table. Needs a C
# compiler (cc); no oracle.
cshim:
	$(JERBUILD) exec --libdirs "$(LIBDIRS)" tools/cshim-test.ss

robustness: corrupt concurrency

clean:
	rm -rf lib
	find . \( -name '*.wpo' -o -name '*.so' \) -delete 2>/dev/null || true

help:
	@echo "jsqlite -- SQLite3-compatible engine in Jerboa Scheme"
	@echo ""
	@echo "  make build    Compile-check all production modules"
	@echo "  make unit     Run unit tests (tests/unit/*.ss)"
	@echo "  make test     Run unit tests (default acceptance gate)"
	@echo "  make corrupt  Malformed-database corpus robustness test (N=, SEED=)"
	@echo "  make concurrency Multi-process write-locking stress test (N=)"
	@echo "  make cshim    C ABI shim: a C driver runs jsqlite prepared statements (needs cc)"
	@echo "  make robustness  corrupt + concurrency"
	@echo "  make clean    Remove build artifacts"
