# Makefile for SLS project with automatic header dependencies

CC ?= gcc
CFLAGS ?= -std=c99 -Wall -Wextra -Werror -g -Iinclude -MMD -MP
LDFLAGS ?=
CTESTFLAGS ?= -std=c99 -Wall -Wextra -Wno-unused-function -Werror -g -O0 -Iinclude -MMD -MP

SRCDIR := src
OBJDIR := obj
BINDIR := bin
TESTDIR := tests

TARGET := $(BINDIR)/sls
TEST_TARGET := $(BINDIR)/sls_tests

SOURCES := $(wildcard $(SRCDIR)/*.c)
OBJECTS := $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SOURCES))
NON_MAIN_OBJECTS := $(filter-out $(OBJDIR)/main.o,$(OBJECTS))

TEST_SOURCES := $(wildcard $(TESTDIR)/*.c)
TEST_OBJECTS := $(patsubst $(TESTDIR)/%.c,$(OBJDIR)/%.o,$(TEST_SOURCES))

# Include dependency files if they exist
-include $(OBJECTS:.o=.d) $(TEST_OBJECTS:.o=.d)

.PHONY: all build run test clean

# Default: build main program
all: $(TARGET)

# Compile object files
build: $(OBJECTS)

# Rule to compile .c -> .o (handles both src and tests)
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
	$(CC) $(CFLAGS) -c $< -o $@

$(OBJDIR)/%.o: $(TESTDIR)/%.c | $(OBJDIR)
	$(CC) $(CTESTFLAGS) -c $< -o $@

# Link main program
$(TARGET): $(OBJECTS) | $(BINDIR)
	$(CC) $(LDFLAGS) $^ -o $@ -lm

# Run main program
run: $(TARGET)
	@echo "Running $(TARGET)..."
	./$(TARGET)

test_cases: ../SLS_Tests/yaml_to_c_tests.py ../SLS_Tests/cases.yaml
	python3 ../SLS_Tests/yaml_to_c_tests.py ../SLS_Tests/cases.yaml ./tests/lexer_tests.c

# Build test runner executable
$(TEST_TARGET): $(TEST_OBJECTS) $(NON_MAIN_OBJECTS) | $(BINDIR)
	$(CC) $(LDFLAGS) $^ -o $@ -lm

build_tests: test_cases $(TEST_TARGET)

# Run tests
debug: build_tests
	gdb ./$(TEST_TARGET)

# Run tests
test: test_cases $(TEST_TARGET)
	@echo "Running tests..."
	./$(TEST_TARGET)

# Create directories if missing
$(BINDIR):
	mkdir -p $(BINDIR)

$(OBJDIR):
	mkdir -p $(OBJDIR)

# Remove build artifacts
clean:
	rm -rf $(OBJDIR) $(BINDIR)
