DISTROS=debian10 ubuntu1910 ubuntu2004
VERSION=$(shell dpkg-parsechangelog --show-field Version)
PROJECTNAME=webserver
PLUGINS= \
         cgi \
         fcgi \
         redirect \
         static-files \
         statistics \
         webbox \
         weblog

CXX=clang++-10

ifeq ($(shell which $(CXX)),)
CXX=clang++
endif

ifeq ($(shell which $(CXX)),)
CXX=g++-9
endif

ifeq ($(shell which $(CXX)),)
CXX=g++
endif

ifeq ($(CXXFLAGS),)
#CXXFLAGS=-O2 -DNDEBUG
CXXFLAGS=-O0 -g -D_DEBUG
endif
# -fprofile-instr-generate -fcoverage-mapping
# gcc:--coverage

CXXFLAGS+= -Wall -I. -DVERSION=\"$(VERSION)\" -fPIE

CXXFLAGS+= -pthread
ifeq ($(CXX),clang++-10)
CXXFLAGS+=-std=c++20 #-stdlib=libc++
else
CXXFLAGS+=-std=c++17
endif

CXXTESTFLAGS=-Igoogletest/include -Igooglemock/include/ -Igoogletest -Igooglemock

LIBS=\
-lboost_context \
-lboost_filesystem \
-lboost_timer \
-lboost_system \
-lcrypt \
-lpthread \
-lssl -lcrypto \
-ldl \
-lcommon

#-lboost_coroutine \
#-lboost_program_options \
#-lboost_thread \
#-lboost_regex \

ifeq ($(CXX),clang++-10)
LIBS+= \
-fuse-ld=lld-10 \
-lstdc++
#-lc++ \
#-lc++abi
#-lc++fs
#-lstdc++fs
else
LIBS+= \
-lstdc++ \
-lstdc++fs
endif

LDFLAGS+=-pie -Llibcommon

PROGSRC=\
    auth.cpp \
    base64.cpp \
    config.cpp \
    file.cpp \
    http.cpp \
    https.cpp \
    os.cpp \
    plugin.cpp \
    privileges.cpp \
    response.cpp \
    statistics.cpp \
    server.cpp

TESTSRC=\
    test-webserver.cpp \
    googlemock/src/gmock-all.cpp \
    googletest/src/gtest-all.cpp \
    $(PROGSRC)

SRC=$(PROGSRC) webserver.cpp

build: $(PROJECTNAME) test-$(PROJECTNAME)
	+set -e ; for i in $(PLUGINS) ; do make -C plugins/$$i ; done
	./test-$(PROJECTNAME)

all: build
	./webserver -c webserver.conf

# testsuite ----------------------------------------------
test-$(PROJECTNAME): $(TESTSRC:.cpp=.o)
	$(CXX) $(LDFLAGS) $^ $(LDLIBS) $(LIBS) -o $@

$(PROJECTNAME): libcommon/libcommon.a $(SRC:.cpp=.o)
	$(CXX) $(LDFLAGS) $^ $(LDLIBS) $(LIBS) -o $@

libcommon/libcommon.a:
	$(MAKE) -C libcommon

dep: $(TESTSRC:.cpp=.d)

%.d: %.cpp
	$(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -MM -MP -MF $@ -c $<

%.o: %.cpp %.d
	$(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@

googletest/src/%.o: googletest/src/%.cc
	$(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@

# dependencies

ADD_DEP=Makefile

install:
	mkdir -p $(DESTDIR)/usr/bin
	cp webserver $(DESTDIR)/usr/bin

	mkdir -p $(DESTDIR)/usr/lib/webserver/plugins
	set -e ; for i in $(PLUGINS) ; do make -C plugins/$$i install ; done

	mkdir -p $(DESTDIR)/usr/local/lib/webserver/plugins

	#mkdir -p $(DESTDIR)/etc
	#cp webserver.conf $(DESTDIR)/etc/webserver.conf

# misc ---------------------------------------------------
deb:
	# build binary deb package
	dpkg-buildpackage -rfakeroot

deb-src:
	dh_clean
	dh_auto_clean
	dpkg-source -b -I.git -Iresult .

$(DISTROS): deb-src
	sudo pbuilder build --basetgz /var/cache/pbuilder/$@.tgz --buildresult result/$@ ../webserver_$(VERSION).dsc
	debsign result/$@/webserver_$(VERSION)_amd64.changes

debs: $(DISTROS)

clean:
	-rm -f test-$(PROJECTNAME) $(PROJECTNAME)
	-rm -f plugins/*.so
	-find . -name '*.o' -o -name '*.d' -o -name '*.gcno' -o -name '*.gcda' | xargs rm -f
	for i in $(PLUGINS) ; do make -C plugins/$$i clean ; done
	$(MAKE) -C libcommon clean

DISTFILES= \
	archive.h \
	auth.cpp \
	auth.h \
	base64.cpp \
	base64.h \
	config.cpp \
	config.h \
	file.cpp \
	file.h \
	http.cpp \
	http.h \
	https.cpp \
	https.h \
	os.cpp \
	os.h \
	plugin.cpp \
	plugin.h \
	plugin_interface.h \
	privileges.cpp \
	privileges.h \
	response.cpp \
	response.h \
	server.cpp \
	server.h \
	statistics.cpp \
	statistics.h \
	test-webserver.cpp \
	webserver.cpp \
	webserver.1 \
	README.txt \
	LICENSE.txt \
	Makefile \
	googletest \
	googlemock \
	debian/changelog \
	debian/compat \
	debian/control \
	debian/copyright \
	debian/README.Debian \
	debian/rules \
	debian/source/format \
	debian/webserver.conf \
	debian/webserver.dirs \
	debian/webserver.docs \
	debian/webserver.install \
	debian/webserver.manpages \
	debian/webserver.service \
	libcommon/Makefile \
	libcommon/mime.h \
	libcommon/mime.cpp \
	plugins/cgi/cgi.h \
	plugins/cgi/Makefile \
	plugins/cgi/cgi.cpp \
	plugins/fcgi/Makefile \
	plugins/fcgi/fastcgi.h \
	plugins/fcgi/fcgi.h \
	plugins/fcgi/fcgi.cpp \
	plugins/fcgi/fcgiid.h \
	plugins/fcgi/fcgiid.cpp \
	plugins/fcgi/socket.h \
	plugins/fcgi/socket.cpp \
	plugins/webbox/file.h \
	plugins/webbox/file.cpp \
	plugins/webbox/stringutil.cpp \
	plugins/webbox/stringutil.h \
	plugins/webbox/webbox.h \
	plugins/webbox/html/refresh-inverted.png \
	plugins/webbox/html/directory.png \
	plugins/webbox/html/file.png \
	plugins/webbox/html/menu.png \
	plugins/webbox/html/webbox.css \
	plugins/webbox/html/favicon.ico \
	plugins/webbox/html/index.html \
	plugins/webbox/html/webbox.js \
	plugins/webbox/Makefile \
	plugins/webbox/webbox.cpp \
	plugins/weblog/weblog.h \
	plugins/weblog/procmail/procmailrc \
	plugins/weblog/procmail/procmail.sh \
	plugins/weblog/stringutil.h \
	plugins/weblog/stringutil.cpp \
	plugins/weblog/Makefile \
	plugins/weblog/weblog.cpp \
	plugins/redirect/Makefile \
	plugins/redirect/redirect.h \
	plugins/redirect/redirect.cpp \
	plugins/static-files/static-files.h \
	plugins/static-files/static-files.cpp \
	plugins/static-files/Makefile \
	plugins/statistics/statistics.h \
	plugins/statistics/Makefile \
	plugins/statistics/statistics.cpp
	
dist: clean
	rm -rf $(PROJECTNAME)-$(VERSION)
	mkdir $(PROJECTNAME)-$(VERSION)
	cp --parents -r $(DISTFILES) $(PROJECTNAME)-$(VERSION)
	tar cfJ ../$(PROJECTNAME)-$(VERSION).tar.xz $(PROJECTNAME)-$(VERSION)
	rm -rf $(PROJECTNAME)-$(VERSION)
	ls -l ../$(PROJECTNAME)-$(VERSION).tar.xz

.PHONY: clean all zip install deb deb-src debs all $(DISTROS)

-include $(wildcard $(SRC:.cpp=.d))