INC_PATH = inc
SRC_PATH = src
OBJ_PATH = obj
BIN_PATH = bin
TMP_PATH = tmp

PRSONA_PATH = .
PRSONA_INC_PATH = $(PRSONA_PATH)/$(INC_PATH)
PRSONA_SRC_PATH = $(PRSONA_PATH)/$(SRC_PATH)
PRSONA_OBJ_PATH = $(PRSONA_PATH)/$(OBJ_PATH)
PRSONA_BIN_PATH = $(PRSONA_PATH)/$(BIN_PATH)
PRSONA_TMP_PATH = $(PRSONA_PATH)/$(TMP_PATH)

BGN_PATH = ../BGN2/bgn2
BGN_INC_PATH = $(BGN_PATH)/$(INC_PATH)
BGN_SRC_PATH = $(BGN_PATH)/$(SRC_PATH)
BGN_OBJ_PATH = $(BGN_PATH)/$(OBJ_PATH)
BGN_BIN_PATH = $(BGN_PATH)/$(BIN_PATH)

666_PATH = ../BGN2/dclxvi-20130329
666_INC_PATH = $(666_PATH)/$(INC_PATH)
666_SRC_PATH = $(666_PATH)/$(SRC_PATH)
666_OBJ_PATH = $(666_PATH)/$(OBJ_PATH)
666_BIN_PATH = $(666_PATH)/$(BIN_PATH)

MG_PATH = ../civetweb
MG_INC_PATH = $(MG_PATH)/include
MG_OBJ_PATH = $(MG_PATH)/out/src

CPP = g++
CPPFLAGS = -std=c++14 -Wall -I$(PRSONA_INC_PATH) -I$(BGN_INC_PATH) -I$(666_INC_PATH) -I$(MG_INC_PATH) -O2
CPPTESTFLAGS = -std=c++14 -Wall -I$(PRSONA_INC_PATH) -I$(BGN_INC_PATH) -I$(666_INC_PATH) -I$(MG_INC_PATH) -g
LDFLAGS = -lgmp -lgmpxx -lssl -lcrypto -lpthread
NETWORK_LDFLAGS = -ldl
LDTESTFLAGS = -lgmp -lgmpxx -lssl -lcrypto -g

CC = gcc
CFLAGS = -std=c99 -O3 -fomit-frame-pointer -I$(666_INC_PATH) -I$(MG_INC_PATH)
C_LDFLAGS = -lm

all : localTest server client orchestrator queue

localTest: $(PRSONA_BIN_PATH) $(PRSONA_OBJ_PATH) $(BGN_OBJ_PATH) $(666_OBJ_PATH) $(PRSONA_BIN_PATH)/localTest

server: $(PRSONA_BIN_PATH) $(PRSONA_OBJ_PATH) $(BGN_OBJ_PATH) $(666_OBJ_PATH) $(PRSONA_TMP_PATH) $(PRSONA_BIN_PATH)/server
client: $(PRSONA_BIN_PATH) $(PRSONA_OBJ_PATH) $(BGN_OBJ_PATH) $(666_OBJ_PATH) $(PRSONA_TMP_PATH) $(PRSONA_BIN_PATH)/client
orchestrator: $(PRSONA_BIN_PATH) $(PRSONA_OBJ_PATH) $(BGN_OBJ_PATH) $(666_OBJ_PATH) $(PRSONA_TMP_PATH) $(PRSONA_BIN_PATH)/orchestrator
queue: $(PRSONA_BIN_PATH) $(PRSONA_BIN_PATH)/queue

$(PRSONA_TMP_PATH):
	mkdir -p $@

$(PRSONA_BIN_PATH):
	mkdir -p $@

$(PRSONA_OBJ_PATH):
	mkdir -p $@

$(BGN_OBJ_PATH):
	mkdir -p $@

$(666_OBJ_PATH):
	mkdir -p $@

$(MG_OBJ_PATH):
	mkdir -p $@

PRSONA_FULL_SRC = $(wildcard $(PRSONA_SRC_PATH)/*.cpp)
PRSONA_FULL_NETWORK_SRC = $(wildcard $(PRSONA_SRC_PATH)/network*.cpp)
PRSONA_SRC = $(filter-out $(PRSONA_FULL_NETWORK_SRC) $(wildcard $(PRSONA_SRC_PATH)/*Main.cpp), $(PRSONA_FULL_SRC)) 
PRSONA_SHARED_NETWORK_OBJ = $(PRSONA_OBJ_PATH)/networking.o
PRSONA_SERVER_NETWORK_OBJ = $(PRSONA_OBJ_PATH)/networkServer.o
PRSONA_CLIENT_NETWORK_OBJ = $(PRSONA_OBJ_PATH)/networkClient.o
PRSONA_ORCHESTRATOR_NETWORK_OBJ = $(PRSONA_OBJ_PATH)/networkOrchestrator.o
PRSONA_NETWORK_OBJ = $(patsubst $(PRSONA_SRC_PATH)/%.cpp, $(PRSONA_OBJ_PATH)/%.o, $(PRSONA_NETWORK_SRC))
PRSONA_OBJ = $(patsubst $(PRSONA_SRC_PATH)/%.cpp, $(PRSONA_OBJ_PATH)/%.o, $(PRSONA_SRC))

$(PRSONA_OBJ_PATH)/%.o: $(PRSONA_SRC_PATH)/%.cpp
	$(CPP) $(CPPFLAGS) -DQHASM -c -o $@ $< 

BGN_FULL_SRC = $(wildcard $(BGN_SRC_PATH)/*.cpp)
BGN_SRC = $(filter-out $(BGN_SRC_PATH)/main.cpp, $(BGN_FULL_SRC)) 
BGN_OBJ = $(patsubst $(BGN_SRC_PATH)/%.cpp, $(BGN_OBJ_PATH)/%.o, $(BGN_SRC))

$(BGN_OBJ_PATH)/%.o: $(BGN_SRC_PATH)/%.cpp
	$(CPP) $(CPPFLAGS) -DQHASM -c -o $@ $< 

666_ALL_C_SRC = $(wildcard $(666_SRC_PATH)/*.c)
666_C_SRC = $(filter-out $(666_SRC_PATH)/bilintest.c $(666_SRC_PATH)/speedtest.c $(666_SRC_PATH)/test_curvepoint_multiscalar.c $(666_SRC_PATH)/test_twistpoint_multiscalar.c $(666_SRC_PATH)/twistpoint_fp2_multiscalar.c $(666_SRC_PATH)/curvepoint_fp_multiscalar.c, $(666_ALL_C_SRC))
666_C_OBJ = $(patsubst $(666_SRC_PATH)/%.c, $(666_OBJ_PATH)/%_c_with_as.o, $(666_C_SRC))

$(666_OBJ_PATH)/%_c_with_as.o: $(666_SRC_PATH)/%.c $(666_INC_PATH)/%.h
	$(CC) $(CFLAGS) -DQHASM -c -o $@ $<

666_AS_SRC = $(wildcard $(666_SRC_PATH)/*.s)
666_AS_OBJ = $(patsubst $(666_SRC_PATH)/%.s, $(666_OBJ_PATH)/%_as.o, $(666_AS_SRC))

$(666_OBJ_PATH)/%_as.o: $(666_SRC_PATH)/%.s
	$(CC) $(CFLAGS) -fPIC -c -o $@ $^

$(BGN_OBJ_PATH)/bgn.a: $(666_AS_OBJ) $(666_C_OBJ) $(BGN_OBJ)
	rm -f $@
	ar cr $@ $^

MG_OBJ += $(MG_OBJ_PATH)/civetweb.o
MG_OBJ += $(MG_OBJ_PATH)/CivetServer.o

$(MG_OBJ_PATH)/%.o: 
	make -C ../civetweb WITH_WEBSOCKET=1 WITH_CPP=1 WITH_SERVER_STATS=1 lib

$(PRSONA_BIN_PATH)/localTest: $(PRSONA_OBJ_PATH)/localMain.o $(PRSONA_OBJ) $(BGN_OBJ_PATH)/bgn.a
	$(CPP) $(CPPFLAGS) -no-pie -o $@ $^ $(LDFLAGS)

$(PRSONA_BIN_PATH)/server: $(PRSONA_OBJ_PATH)/serverMain.o $(PRSONA_OBJ) $(PRSONA_SHARED_NETWORK_OBJ) $(PRSONA_SERVER_NETWORK_OBJ) $(MG_OBJ) $(BGN_OBJ_PATH)/bgn.a
	$(CPP) $(CPPFLAGS) -no-pie -o $@ $^ $(LDFLAGS) $(NETWORK_LDFLAGS)

$(PRSONA_BIN_PATH)/client: $(PRSONA_OBJ_PATH)/clientMain.o $(PRSONA_OBJ) $(PRSONA_SHARED_NETWORK_OBJ) $(PRSONA_CLIENT_NETWORK_OBJ) $(MG_OBJ) $(BGN_OBJ_PATH)/bgn.a
	$(CPP) $(CPPFLAGS) -no-pie -o $@ $^ $(LDFLAGS) $(NETWORK_LDFLAGS)

$(PRSONA_BIN_PATH)/orchestrator: $(PRSONA_OBJ_PATH)/orchestratorMain.o $(PRSONA_OBJ) $(PRSONA_SHARED_NETWORK_OBJ) $(PRSONA_ORCHESTRATOR_NETWORK_OBJ) $(MG_OBJ) $(BGN_OBJ_PATH)/bgn.a
	$(CPP) $(CPPFLAGS) -no-pie -o $@ $^ $(LDFLAGS) $(NETWORK_LDFLAGS)

$(PRSONA_BIN_PATH)/queue: $(PRSONA_SRC_PATH)/experimentQueueMain.cpp
	$(CPP) $(CPPFLAGS) -o $@ $^

.PHONY: clean

clean: prsona_clean bgn_clean 666_clean mg_clean

pclean: prsona_clean

seemly:
	-rm $(PRSONA_TMP_PATH)/*
	-pkill -u tmgurtle client
	-pkill -u tmgurtle server

demolition:
	-scripts/bringDownTestServers.sh

prsona_clean: 
	-rm $(PRSONA_BIN_PATH)/*
	-rm $(PRSONA_OBJ_PATH)/*

bgn_clean:
	-rm $(BGN_OBJ_PATH)/*

666_clean:
	-rm $(666_OBJ_PATH)/*

mg_clean: 
	make -C ../civetweb clean