# 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.

# T6 -- DVX BASIC IDE under the dvxtest harness.
#
# Builds the IDE sources (ideMain.c is #included by testIde.c so the
# tests can inspect the IDE's file-scope state), the BASIC compiler,
# runtime, form runtime and basBuild natively, links them with the host
# libdvx and the dvxtest runner, and drives ideMain's appMain through
# menu commands, queued input and scripted dialogs.  Shell functions the
# IDE calls directly are supplied by ideStubs.c.  bin/host/bascomp is
# built too: it provides the STUB resource for Make Executable and the
# reference output the test byte-compares against.

include ../dvxtest/dvxtest.mk

.DEFAULT_GOAL := all

BASIC      := $(DVXTEST_ROOT)/src/apps/kpunch/dvxbasic
SHELL_DIR  := $(DVXTEST_ROOT)/src/libs/kpunch/dvxshell
BINDIR     := $(DVXTEST_BINDIR)/ide
# COV builds use the instrumented compiler/runner so their executions
# count toward stub/ coverage.
# BASCOMPREL/BASRUNREL are the literal (relative) target names the
# dvxbasic Makefile declares its rules with; absolute paths only make
# when the binaries already exist.
ifeq ($(COV),1)
BASCOMP    := $(DVXTEST_ROOT)/obj/hostcov/basic/bascomp
BASRUN     := $(DVXTEST_ROOT)/obj/hostcov/basic/basrun
BASCOMPREL := ../../../../obj/hostcov/basic/bascomp
BASRUNREL  := ../../../../obj/hostcov/basic/basrun
else
BASCOMP    := $(DVXTEST_ROOT)/bin/host/bascomp
BASRUN     := $(DVXTEST_ROOT)/bin/host/basrun
BASCOMPREL := ../../../../bin/host/bascomp
BASRUNREL  := ../../../../bin/host/basrun
endif
FIXTURES   := $(abspath fixtures)
TARGET     := $(BINDIR)/testIde
STUBTARGET := $(BINDIR)/testStub

IDE_SRCS   := ideDesigner.c ideProperties.c ideProject.c ideMenuEditor.c ideToolbox.c
COMP_SRCS  := lexer.c parser.c codegen.c symtab.c strip.c obfuscate.c compact.c
RT_SRCS    := vm.c values.c serialize.c
FRM_SRCS   := formrt.c frmParser.c basNativeHost.c

OBJS       := $(BINDIR)/testIde.o $(BINDIR)/ideStubs.o
OBJS       += $(patsubst %.c,$(BINDIR)/ide/%.o,$(IDE_SRCS))
OBJS       += $(patsubst %.c,$(BINDIR)/compiler/%.o,$(COMP_SRCS))
OBJS       += $(patsubst %.c,$(BINDIR)/runtime/%.o,$(RT_SRCS))
OBJS       += $(patsubst %.c,$(BINDIR)/formrt/%.o,$(FRM_SRCS))
OBJS       += $(BINDIR)/basBuild.o

STUBOBJS   := $(BINDIR)/testStub.o
STUBOBJS   += $(patsubst %.c,$(BINDIR)/runtime/%.o,$(RT_SRCS))
STUBOBJS   += $(patsubst %.c,$(BINDIR)/formrt/%.o,$(FRM_SRCS))

CFLAGS     := $(DVXTEST_CFLAGS) -Wno-stringop-truncation -I$(BASIC) -I$(BASIC)/ide -I$(SHELL_DIR) -DIDETEST_FIXTURE_DIR='"$(FIXTURES)"' -DIDETEST_BASCOMP='"$(BASCOMP)"'
BAS_HDRS   := $(wildcard $(BASIC)/*.h $(BASIC)/ide/*.h $(BASIC)/compiler/*.h $(BASIC)/runtime/*.h $(BASIC)/formrt/*.h)

.PHONY: all run cli libs bascomp clean

all: run

libs: dvxtest-libs

bascomp:
	$(MAKE) -C $(BASIC) $(BASCOMPREL) $(BASRUNREL)

cli: bascomp
	BASCOMP=$(BASCOMP) BASRUN=$(BASRUN) ./runCli.sh

$(BINDIR)/testIde.o: testIde.c testIdeDesign.c testIdeDebug.c $(BASIC)/ide/ideMain.c $(BAS_HDRS) $(DVXTEST_HDRS) | libs
	@mkdir -p $(BINDIR)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(BINDIR)/testStub.o: testStub.c $(BASIC)/stub/basstub.c $(BAS_HDRS) $(DVXTEST_HDRS) | libs
	@mkdir -p $(BINDIR)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(BINDIR)/ideStubs.o: ideStubs.c $(BAS_HDRS) $(DVXTEST_HDRS) | libs
	@mkdir -p $(BINDIR)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(BINDIR)/ide/%.o: $(BASIC)/ide/%.c $(BAS_HDRS) $(DVXTEST_HDRS) | libs
	@mkdir -p $(dir $@)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(BINDIR)/compiler/%.o: $(BASIC)/compiler/%.c $(BAS_HDRS) | libs
	@mkdir -p $(dir $@)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(BINDIR)/runtime/%.o: $(BASIC)/runtime/%.c $(BAS_HDRS) | libs
	@mkdir -p $(dir $@)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(BINDIR)/formrt/%.o: $(BASIC)/formrt/%.c $(BAS_HDRS) $(DVXTEST_HDRS) | libs
	@mkdir -p $(dir $@)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(BINDIR)/basBuild.o: $(BASIC)/basBuild.c $(BAS_HDRS) | libs
	@mkdir -p $(BINDIR)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(TARGET): $(OBJS) $(DVXTEST_LIB)
	$(HOSTCC) -o $@ $(OBJS) $(DVXTEST_LINK)

$(STUBTARGET): $(STUBOBJS) $(DVXTEST_LIB)
	$(HOSTCC) -o $@ $(STUBOBJS) $(DVXTEST_LINK)

run: $(TARGET) $(STUBTARGET) bascomp
	cd $(BINDIR) && ASAN_OPTIONS=detect_leaks=1 ./testIde
	cd $(BINDIR) && ASAN_OPTIONS=detect_leaks=1 ./testStub
	$(MAKE) cli

clean:
	rm -rf $(BINDIR)
