CC = gcc
CFLAGS = -Wall -Wextra -Isrc/include -Iinclude -ggdb
LDFLAGS = -ldl -rdynamic -ltram

# Install paths
PREFIX ?= /usr/local
DESTDIR ?=

# Directories
SRC_DIR = src
BUILD_DIR = build
BIN_DIR = $(BUILD_DIR)/bin
LIB_DIR = $(BUILD_DIR)/lib
INC_DIR = $(BUILD_DIR)/include
OBJ_DIR = $(BUILD_DIR)/obj

# Output names
EXECUTABLE = $(BIN_DIR)/ground
SHARED_LIB = $(LIB_DIR)/libgroundvm.so
HEADERS = $(INC_DIR)/groundvm.h $(INC_DIR)/groundext.h

# Source files
LIB_SOURCES = $(filter-out $(SRC_DIR)/main.c, $(wildcard $(SRC_DIR)/*.c))
EXE_SOURCES = $(wildcard $(SRC_DIR)/*.c)

# Object files
LIB_OBJECTS = $(LIB_SOURCES:$(SRC_DIR)/%.c=$(OBJ_DIR)/lib_%.o)
EXE_OBJECTS = $(EXE_SOURCES:$(SRC_DIR)/%.c=$(OBJ_DIR)/exe_%.o)

# Default target: build standalone executable
.PHONY: all
all: executable

# Build standalone executable
.PHONY: executable
executable: $(EXECUTABLE)

# Build shared library
.PHONY: library
library: $(SHARED_LIB) $(HEADERS)

# Build both
.PHONY: both
both: executable library

# Link executable
$(EXECUTABLE): $(EXE_OBJECTS) | $(BIN_DIR)
	$(CC) $(EXE_OBJECTS) -o $@ $(LDFLAGS)

# Build shared library
$(SHARED_LIB): $(LIB_OBJECTS) | $(LIB_DIR)
	$(CC) -shared $(LIB_OBJECTS) -o $@ $(LDFLAGS)

# Copy header for library distribution
$(INC_DIR)/%.h: include/%.h | $(INC_DIR)
	cp $< $@

# Compile object files for executable
$(OBJ_DIR)/exe_%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
	$(CC) $(CFLAGS) -c $< -o $@

# Compile object files for shared library (with -fPIC)
$(OBJ_DIR)/lib_%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
	$(CC) $(CFLAGS) -fPIC -c $< -o $@

# Create directories
$(BUILD_DIR) $(BIN_DIR) $(LIB_DIR) $(INC_DIR) $(OBJ_DIR):
	mkdir -p $@

# Clean build artifacts
.PHONY: clean
clean:
	rm -rf $(BUILD_DIR)

# Install executable, library, and header
.PHONY: install
install: both
	mkdir -p $(DESTDIR)$(PREFIX)/bin
	mkdir -p $(DESTDIR)$(PREFIX)/lib
	mkdir -p $(DESTDIR)$(PREFIX)/include
	cp $(EXECUTABLE) $(DESTDIR)$(PREFIX)/bin/
	cp $(SHARED_LIB) $(DESTDIR)$(PREFIX)/lib/
	cp $(HEADERS) $(DESTDIR)$(PREFIX)/include/
	echo "$(DESTDIR)$(PREFIX)/lib" | tee $(DESTDIR)/etc/ld.so.conf.d/cground.conf 
	ldconfig

# Debug: print variables
.PHONY: debug
debug:
	@echo "LIB_SOURCES: $(LIB_SOURCES)"
	@echo "EXE_SOURCES: $(EXE_SOURCES)"
	@echo "LIB_OBJECTS: $(LIB_OBJECTS)"
	@echo "EXE_OBJECTS: $(EXE_OBJECTS)"
