# The MIT License (MIT)
#
# Copyright (C) 2026 Scott Duensing
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.


# Serial stack test suite (T8) -- native host build.
#
# testSerial: compiles packet.c, secHash.c, security.c and secLink.c from
# the shared serial library unmodified against the in-process loopback
# shim (loopShim.c; loopShim.h is -included only to redirect clock()).
# testSerialProxy: links the same sources against the proxy's socket shim
# (sockShim.c) plus proxy.c itself (main renamed via -Dmain) and drives
# the proxy end-to-end over real sockets from testProxy.c.
#
# `make` builds and runs both; `make proxy` runs only the proxy suite;
# `make asan` is the default build; `make plain` builds without sanitizers.
# Binaries and objects live under the host object tree of the SAN/COV
# mode (common.mk), never in bin/.

include ../../common.mk

SERIAL   = ../../libs/kpunch/serial
PROXYDIR = ../../tools/proxy
OBJDIR   = $(HOST_OBJROOT)/test/serial
BINDIR   = $(OBJDIR)
TARGET   = $(BINDIR)/testSerial
CFLAGS   = -O1 -g $(WARNFLAGS) $(DEPFLAGS) $(HOST_INSTFLAGS)
LDFLAGS  = $(HOST_LDFLAGS)

# testSerial interposes secCipherCreate/secDhCreate to drive allocation
# failure paths.  Kept out of LDFLAGS so a coverage LDFLAGS override on
# the command line cannot lose the wraps.
WRAP_LDFLAGS = -Wl,--wrap=secCipherCreate -Wl,--wrap=secDhCreate

# testSerialProxy interposes accept/listen/secLinkOpen the same way, gated
# by environment variables inside testProxy.c.
PROXY_WRAP_LDFLAGS = -Wl,--wrap=accept -Wl,--wrap=listen -Wl,--wrap=secLinkOpen

PROXY_TARGET = $(TARGET)Proxy

OBJS  = $(OBJDIR)/loopShim.o $(OBJDIR)/packet.o $(OBJDIR)/secHash.o \
        $(OBJDIR)/security.o $(OBJDIR)/secLink.o $(OBJDIR)/testSerial.o
POBJS = $(OBJDIR)/sockShim.o $(OBJDIR)/sockPacket.o $(OBJDIR)/secHash.o \
        $(OBJDIR)/security.o $(OBJDIR)/sockSecLink.o $(OBJDIR)/proxyMain.o \
        $(OBJDIR)/testProxy.o

.PHONY: all build asan plain proxy clean

all: build
	$(TARGET)
	$(PROXY_TARGET)

build: $(TARGET) $(PROXY_TARGET)

# Kept for compatibility: `make asan` is now the default build.
asan: all

plain:
	$(MAKE) SAN=0 all

proxy: $(PROXY_TARGET)
	$(PROXY_TARGET)

# Uses HOSTCC (not CC, which common.mk points at the DOS cross compiler).
$(TARGET): $(OBJS) | $(BINDIR)
	$(HOSTCC) $(LDFLAGS) $(WRAP_LDFLAGS) -o $@ $(OBJS)

$(PROXY_TARGET): $(POBJS) | $(BINDIR)
	$(HOSTCC) $(LDFLAGS) $(PROXY_WRAP_LDFLAGS) -o $@ $(POBJS)

$(OBJDIR)/loopShim.o: loopShim.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(OBJDIR)/testSerial.o: testSerial.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -I$(SERIAL) -c -o $@ $<

$(OBJDIR)/testProxy.o: testProxy.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -I$(SERIAL) -I$(PROXYDIR) -c -o $@ $<

# Library sources against the loopback shim (clock() redirected).
$(OBJDIR)/packet.o: $(SERIAL)/packet/packet.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -include loopShim.h -c -o $@ $<

$(OBJDIR)/secHash.o: $(SERIAL)/security/secHash.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(OBJDIR)/security.o: $(SERIAL)/security/security.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(OBJDIR)/secLink.o: $(SERIAL)/seclink/secLink.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -include loopShim.h -c -o $@ $<

# The same library sources against the proxy's socket shim, plus proxy.c
# itself with main() renamed so the test harness can fork and call it.
$(OBJDIR)/sockShim.o: $(PROXYDIR)/sockShim.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(OBJDIR)/proxyMain.o: $(PROXYDIR)/proxy.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -Dmain=proxyMain -c -o $@ $<

$(OBJDIR)/sockPacket.o: $(SERIAL)/packet/packet.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -include $(PROXYDIR)/sockShim.h -c -o $@ $<

$(OBJDIR)/sockSecLink.o: $(SERIAL)/seclink/secLink.c $(DVX_MAKEFILES) | $(OBJDIR)
	$(HOSTCC) $(CFLAGS) -include $(PROXYDIR)/sockShim.h -c -o $@ $<

$(sort $(OBJDIR) $(BINDIR)):
	mkdir -p $@

-include $(sort $(OBJS:.o=.d) $(POBJS:.o=.d))

clean:
	rm -rf $(OBJDIR) $(TARGET) $(PROXY_TARGET)
