CC = gcc
CFLAGS = -Wall -Wextra -Wpedantic -std=c11 -Isrc
CARLA_INC = -I/usr/include/carla -I/usr/include/carla/includes
CARLA_LIB = -L/usr/lib/carla -Wl,-rpath,/usr/lib/carla -lcarla_standalone2

# Objects (must be defined before any rules)
CARLA_OBJ       = src/carla_host.o
PLUGINS_OBJ     = src/plugins.o
CLIENT_CMD_OBJ  = src/client_cmd.o

# Test binaries
TEST_PLUGINS_BIN    = test_plugins
TEST_CLIENT_BIN     = test_client
TEST_CARLA_BIN      = test_carla_host
TEST_CLIENT_CMD_BIN = test_client_cmd
TEST_INTEGRATION_BIN = test_integration

all: looper-client test_status_parse

looper-client: src/main.c src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ)
	$(CC) $(CFLAGS) $(CARLA_INC) -o $@ $^ $(CARLA_LIB) -ljack -lncurses

test_status_parse: tests/test_status_parse.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ)
	$(CC) $(CFLAGS) $(CARLA_INC) -o test_status_parse tests/test_status_parse.c src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(CARLA_LIB) -ljack -lncurses

# --- Plugin stubs (now real) ---
$(PLUGINS_OBJ): src/plugins.c src/plugins.h
	$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<

$(CARLA_OBJ): src/carla_host.c src/carla_host.h
	$(CC) -Wall -Wextra -std=c11 -Isrc $(CARLA_INC) -c -o $@ $<

CARLA_TEST_OBJ = src/carla_host_test.o

$(CARLA_TEST_OBJ): src/carla_host.c src/carla_host.h
	$(CC) -Wall -Wextra -std=c11 -Isrc $(CARLA_INC) -DTESTING -c -o $@ $<

$(CLIENT_CMD_OBJ): src/client_cmd.c src/client_cmd.h
	$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<

# --- Plugin tests ---
TEST_PLUGINS_OBJ = tests/test_plugins.o

$(TEST_PLUGINS_OBJ): tests/test_plugins.c src/plugins.h
	$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<

$(TEST_PLUGINS_BIN): $(TEST_PLUGINS_OBJ) $(PLUGINS_OBJ) $(CARLA_OBJ)
	$(CC) $(CFLAGS) -o $@ $^ $(CARLA_LIB) -ljack

# ensure the tests directory exists
$(TEST_PLUGINS_OBJ): | tests

# --- Client command tests ---
TEST_CLIENT_CMD_OBJ = tests/test_client_cmd.o

$(TEST_CLIENT_CMD_OBJ): tests/test_client_cmd.c src/client_cmd.h src/plugins.h
	$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<

$(TEST_CLIENT_CMD_BIN): $(TEST_CLIENT_CMD_OBJ) $(CLIENT_CMD_OBJ) $(PLUGINS_OBJ) $(CARLA_OBJ)
	$(CC) $(CFLAGS) -o $@ $^ $(CARLA_LIB) -ljack

# --- send_command test ---
TEST_CLIENT_OBJ = tests/test_client.o

$(TEST_CLIENT_OBJ): tests/test_client.c src/tui.h
	$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<

$(TEST_CLIENT_BIN): $(TEST_CLIENT_OBJ) src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ)
	$(CC) $(CFLAGS) $(CARLA_INC) -o $@ $^ $(CARLA_LIB) -ljack -lncurses

# --- Carla host tests ---
TEST_CARLA_OBJ = tests/test_carla_host.o

$(TEST_CARLA_OBJ): tests/test_carla_host.c src/carla_host.h
	$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<

$(TEST_CARLA_BIN): $(TEST_CARLA_OBJ) $(CARLA_OBJ)
	$(CC) $(CFLAGS) -o $@ $^ $(CARLA_LIB) -ljack

# --- Integration test (requires TESTING symbol) ---
$(TEST_INTEGRATION_BIN): tests/test_integration.c $(CARLA_TEST_OBJ)
	$(CC) $(CFLAGS) $(CARLA_INC) -DTESTING -o $@ $^ $(CARLA_LIB) -ljack

test: looper-client test_status_parse $(TEST_PLUGINS_BIN) $(TEST_CLIENT_BIN) $(TEST_CARLA_BIN) $(TEST_CLIENT_CMD_BIN) $(TEST_INTEGRATION_BIN)
	./test_status_parse
	./$(TEST_PLUGINS_BIN)
	./$(TEST_CLIENT_BIN)
	./$(TEST_CARLA_BIN)
	./$(TEST_CLIENT_CMD_BIN)
	./$(TEST_INTEGRATION_BIN)

.PHONY: all test clean

clean:
	rm -f looper-client test_status_parse $(TEST_PLUGINS_BIN) $(TEST_CLIENT_BIN) $(TEST_CARLA_BIN) $(TEST_CLIENT_CMD_BIN) $(TEST_INTEGRATION_BIN) *.o tests/*.o src/*.o
