# undoom oracle: instrumented chocolate-doom, headless, bit-exact reference.
#
#   make -C tools/oracle            # clone + patch + build + demos + expected
#   make -C tools/oracle build      # just the instrumented binary
#   make -C tools/oracle demos      # .lmp files from demos/*.txt
#   make -C tools/oracle reference  # run every demo -> build/oracle/<demo>/
#   make -C tools/oracle expected   # copy text outputs into expected/<demo>/
#   make -C tools/oracle clean      # remove build outputs (keeps the clone)
#   make -C tools/oracle distclean  # also remove the chocolate-doom clone
#
# Load discipline: builds run `nice -n 10` with -j2.

ROOT      := $(abspath ../..)
BUILD     := $(ROOT)/build
SRC       := $(BUILD)/chocolate-doom
OBJ       := $(BUILD)/chocolate-doom-build
BIN       := $(OBJ)/src/chocolate-doom
ORACLE    := $(BUILD)/oracle
REPO      := https://github.com/chocolate-doom/chocolate-doom
COMMIT    := 895f581c5d91497bdda0516612da803fe5843e28
PATCH     := $(CURDIR)/chocolate-doom-undoom.patch
STAMP     := $(SRC)/.undoom-patched

DEMO_TXT  := $(wildcard demos/*.txt)
DEMOS     := $(notdir $(DEMO_TXT:.txt=))
DEMO_LMP  := $(patsubst %,$(ORACLE)/demos/%.lmp,$(DEMOS))

JOBS      ?= 2

.PHONY: all build demos reference expected clean distclean

all: build demos reference expected

build: $(BIN)

$(SRC)/CMakeLists.txt:
	mkdir -p $(BUILD)
	git clone $(REPO) $(SRC)
	git -C $(SRC) checkout --detach $(COMMIT)

$(STAMP): $(SRC)/CMakeLists.txt $(PATCH)
	@if git -C $(SRC) apply --reverse --check $(PATCH) 2>/dev/null; then \
	  echo "patch already applied"; \
	elif git -C $(SRC) diff --quiet; then \
	  git -C $(SRC) apply $(PATCH); \
	else \
	  echo "$(SRC) has changes other than our patch; run make distclean" >&2; \
	  exit 1; \
	fi
	touch $@

$(OBJ)/Makefile: $(STAMP)
	mkdir -p $(OBJ)
	cd $(OBJ) && cmake $(SRC) -DCMAKE_BUILD_TYPE=Release \
	  -DENABLE_SDL2_NET=Off -DENABLE_SDL2_MIXER=On

$(BIN): $(OBJ)/Makefile $(STAMP)
	nice -n 10 $(MAKE) -C $(OBJ) -j$(JOBS) chocolate-doom

demos: $(DEMO_LMP)

$(ORACLE)/demos/%.lmp: demos/%.txt mkdemo.py
	mkdir -p $(dir $@)
	python3 -u mkdemo.py $< $@

reference: $(BIN) $(DEMO_LMP)
	for d in $(DEMOS); do \
	  ./run.sh $(ORACLE)/demos/$$d.lmp $(ORACLE)/$$d || exit 1; \
	done

expected: reference
	for d in $(DEMOS); do \
	  mkdir -p expected/$$d; \
	  cp $(ORACLE)/$$d/state.log expected/$$d/state.log; \
	  cp $(ORACLE)/$$d/frames/frames.txt expected/$$d/frames.txt; \
	done

clean:
	rm -rf $(OBJ) $(ORACLE)

distclean: clean
	rm -rf $(SRC)
