PLUGIN := protoc-gen-tarantool
DOC_PLUGIN := protoc-gen-tarantool-doc
GEN_DIR := examples/expected
DOCS_DIR := examples/docs
PROTO_DIR := examples/proto
CONFORMANCE_PROTO_DIR := test/conformance/proto

LUATEST := .rocks/bin/luatest
LUA_PATH_PARTS := \
	./runtime/?/init.lua \
	./runtime/?.lua \
	./$(GEN_DIR)/?.lua \
	./$(GEN_DIR)/?/init.lua \
	./?.lua \
	./?/init.lua \
	./test/?.lua

# semicolon-joined; trailing ;; lets the standard package.path defaults apply
empty :=
space := $(empty) $(empty)
LUA_PATH_JOINED := $(subst $(space),;,$(strip $(LUA_PATH_PARTS)));;

.PHONY: all build build-doc gen gen-full gen-runtime gen-docs goldens \
        test test-suite bench bench-baseline bench-compare \
        bench-wire bench-shapes jit-trace clean

all: build gen test

build:
	go build -o $(PLUGIN) ./cmd/protoc-gen-tarantool

build-doc:
	go build -o $(DOC_PLUGIN) ./cmd/protoc-gen-tarantool-doc

gen: gen-full gen-runtime gen-conformance

# Render Markdown reference docs for example protos. Output is committed
# so the doc plugin's behavior is visible in PR diffs.
gen-docs: build-doc
	mkdir -p $(DOCS_DIR)
	protoc \
		--plugin=./$(DOC_PLUGIN) \
		--tarantool-doc_out=$(DOCS_DIR) \
		-I $(PROTO_DIR) -I options \
		$(PROTO_DIR)/*.proto

gen-full: build
	mkdir -p $(GEN_DIR)
	protoc \
		--plugin=./$(PLUGIN) \
		--tarantool_out=$(GEN_DIR) \
		--tarantool_opt=mode=full,prefix=full \
		-I $(PROTO_DIR) -I options \
		$(PROTO_DIR)/*.proto

gen-runtime: build
	mkdir -p $(GEN_DIR)
	protoc \
		--plugin=./$(PLUGIN) \
		--tarantool_out=$(GEN_DIR) \
		--tarantool_opt=mode=runtime,prefix=runtime \
		-I $(PROTO_DIR) -I options \
		$(PROTO_DIR)/*.proto

# Conformance + Google test_messages_proto3 are needed by cmd/conformance-runner.lua
# and the conformance self-test. Only the `full` mode is required by the runner.
gen-conformance: build
	mkdir -p $(GEN_DIR)
	protoc \
		--plugin=./$(PLUGIN) \
		--tarantool_out=$(GEN_DIR) \
		--tarantool_opt=mode=full,prefix=full \
		-I $(CONFORMANCE_PROTO_DIR) -I options \
		$(CONFORMANCE_PROTO_DIR)/*.proto
	protoc \
		--plugin=./$(PLUGIN) \
		--tarantool_out=$(GEN_DIR) \
		--tarantool_opt=mode=runtime,prefix=runtime \
		-I $(CONFORMANCE_PROTO_DIR) -I options \
		$(CONFORMANCE_PROTO_DIR)/*.proto

# Regenerate the interop golden corpus from .txtpb sources using mainline
# protoc. Run only when fixtures change; the generated .bin files are committed.
goldens:
	@for f in test/interop/fixtures/*.txtpb; do \
		type=$$(awk '/^# type:/ {print $$3; exit}' $$f); \
		out=$${f%.txtpb}.bin; \
		echo "  protoc --encode=$$type < $$f > $$out"; \
		protoc --encode=$$type -I $(PROTO_DIR) -I options $(PROTO_DIR)/hello.proto < $$f > $$out || exit $$?; \
	done

test: gen
	LUA_PATH="$(LUA_PATH_JOINED)" $(LUATEST) -v test/

# Microbenchmark: throughput + allocation per op across 5 payload sizes,
# both codegen modes. Throughput numbers print to stderr (informational —
# they vary with CPU load); the JSON document on stdout is the full record.
bench: gen
	tarantool bench/bench.lua --print

# Overwrite bench/baseline.json with current alloc-per-op numbers. Run on
# a quiet machine; allocs are deterministic to ~10 bytes so the file is
# hardware-independent.
bench-baseline: gen
	tarantool bench/bench.lua --baseline

# Fail with exit 1 if any alloc-per-op grows by >5% vs the committed
# baseline. Wire into CI to gate PRs.
bench-compare: gen
	tarantool bench/bench.lua --compare

# Per-helper microbenchmark for the wire layer (encode/decode of every
# primitive + tag + skip + UTF-8). Use when tuning runtime/pb/wire.lua
# to confirm a change moved the helper-level ns/op as expected.
bench-wire: gen
	tarantool bench/wire_bench.lua

# Workload-variety benchmark. Runs encode + decode for several Person
# (and Event / Result) shapes — scalar-heavy, packed-ints, nested
# friends, maps, oneof, WKT — so shape-specific regressions surface
# instead of being averaged out by bench/bench.lua's single shape.
bench-shapes: gen
	tarantool bench/shapes_bench.lua

# Trace-stability gate: assert every hot encode/decode path JIT-compiles
# without fatal aborts (NYI bytecode, blacklisting, persistent type
# instability) in our own source files. Runs as a standalone tarantool
# script — luatest's framework on macOS arm64 exhausts JIT mcode pages
# before tests run, masking the real abort reasons.
jit-trace: gen
	tarantool bench/jit_trace.lua

clean:
	rm -f $(PLUGIN)
	rm -rf $(GEN_DIR)
