# This makefile is part of Proteinortho.
##########################################

# Run 'make' for compiling everything in the current directory (using the installed version of lapack in e.g. /usr/lib/, you can install lapack with e.g. apt-get install libatlas3-base or liblapack3)
# Run 'make USELAPACK=FALSE' for a version without(!) LAPACK (only power iteration is used)
# Run 'make USEPRECOMPILEDLAPACK=FALSE' for directly recompiling the provided lapack version 3.8.0 and linking dynamically 

# Run 'make install' for installing the compiled files to /usr/local/bin
# Run 'make install INSTALLDIR=/home/paul/...' for local installation OR 'make install PREFIX=/home/paul/...' 

##########################
## enviroment variables ##
##########################

INSTALLDIR=/usr/local/bin
USELAPACK=TRUE
USEPRECOMPILEDLAPACK=TRUE
LIBRARY_PATH=/usr/local/lib
INCLUDE_PATH=/usr/local/include

UNAME_S=$(shell uname -s)_$(shell uname -m)
BUILDDIR=src/BUILD/$(UNAME_S)

ifdef PREFIX
INSTALLDIR=$(PREFIX)
endif

ifdef LAPACK
USELAPACK=$(LAPACK)
endif

CPP=g++
C=gcc
CPPFLAGS+=-Wall -O3 -std=gnu++11 -Wno-unused-result

IS_COLOR_COMPATIBLE:=$(shell tput color 2>/dev/null)
ifdef IS_COLOR_COMPATIBLE
RED=\033[1;31m
GREEN=\033[1;32m
ORANGE=\033[1;33m
NC=\033[0m
endif

##############
# MAKEFILE : #
##############

dir_guard=@if [ ! -d $(BUILDDIR) ]; then echo "Creating build directory ..."; mkdir -p $(BUILDDIR); fi

all:$(BUILDDIR)/grepfasta.pl $(BUILDDIR)/formatU.pl $(BUILDDIR)/do_mcl.pl $(BUILDDIR)/po2tree.pl $(BUILDDIR)/po2html.pl $(BUILDDIR)/proteinortho2xml.pl $(BUILDDIR)/proteinortho_singletons.pl $(BUILDDIR)/ffadj_mcs.py $(BUILDDIR)/proteinortho_clustering $(BUILDDIR)/graphMinusRemovegraph $(BUILDDIR)/cleanupblastgraph $(BUILDDIR)/po_tree
	@echo "[100%] $(GREEN)Everything is compiled with no errors.$(NC)"

# makedir:
# 	@if [ ! -d $(BUILDDIR) ]; then echo "[  0%] Creating build directory ..."; \
# 	mkdir -p $(BUILDDIR); fi

$(BUILDDIR)/grepfasta.pl: src/grepfasta.pl
	$(dir_guard)
	@cp $< $@
$(BUILDDIR)/do_mcl.pl: src/do_mcl.pl
	$(dir_guard)
	@cp $< $@
$(BUILDDIR)/formatU.pl: src/formatU.pl
	$(dir_guard)
	@cp $< $@
$(BUILDDIR)/po2html.pl: src/po2html.pl
	$(dir_guard)
	@cp $< $@
$(BUILDDIR)/proteinortho2xml.pl: src/proteinortho2xml.pl
	$(dir_guard)
	@cp $< $@
$(BUILDDIR)/proteinortho_singletons.pl: src/proteinortho_singletons.pl
	$(dir_guard)
	@cp $< $@
$(BUILDDIR)/po2tree.pl: src/po2tree.pl
	$(dir_guard)
	@cp $< $@
$(BUILDDIR)/ffadj_mcs.py: src/ffadj_mcs.py
	$(dir_guard)
	@cp $< $@

# 1. Try to compile statically with LAPACK
# 2. try to compile dynamically with the given lapack lib in src/
$(BUILDDIR)/proteinortho_clustering: src/proteinortho_clustering.cpp
	$(dir_guard)
	@echo "[ 10%] Prepare proteinortho_clustering ..."
ifeq ($(USELAPACK),TRUE)
ifeq ($(USEPRECOMPILEDLAPACK),TRUE)
	@echo "[ 20%] Building **proteinortho_clustering** with LAPACK (static linking)";
	@$(CPP) -std=c++11 -Wall -O3 -fopenmp  -o $@ $< -Wall -std=c++11 -O3 -static -I$(INCLUDE_PATH) -L$(LIBRARY_PATH) -llapack -lblas -lgfortran -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive && ([ $$? -eq 0 ] ) || ( \
		echo "......$(ORANGE)static linking failed, now I try to recompile lapack (v.3.1.0) and then compile proteinortho_clustering with dynamic linking.$(NC)"; \
		echo "......[ 33%] Extracting the LAPACK library"; \
		if [ ! -d src/lapack ]; then cd src; tar -xvf lapack-3.1.0.tar.bz2 > /dev/null 2>&1; cd ..; fi; \
		echo "......[ 66%] Compiling the LAPACK library (using cmake + make)"; \
		if [ ! -f src/lapack/build/lib/liblapack.a ]; then cd src/lapack/build; cmake .. > /dev/null 2>&1; make all -j4 > /dev/null 2>&1; cd ../../.. ; fi; \
		echo "......[ 99%] Building **proteinortho_clustering** with LAPACK (dynamic linking)"; \
		$(CPP) -std=c++11 -Wall -O3 -fopenmp -flto $(LDFLAGS) -o $@ $< -Isrc/lapack/build/include/ -Lsrc/lapack/build/lib/ -llapack -lblas -I$(INCLUDE_PATH) -L$(LIBRARY_PATH) -lgfortran && echo "......OK dynamic linking was successful for proteinortho_clustering!"; )
	@if [ ! -e $(BUILDDIR)/proteinortho_clustering ]; then echo "proteinortho_clustering compilation failed"; false; fi
else
	echo "[ 15%] Extracting the LAPACK library"; \
	if [ ! -d src/lapack ]; then cd src; tar -xvf lapack-3.1.0.tar.bz2 > /dev/null 2>&1; cd ..; fi; \
	echo "[ 18%] Compiling the LAPACK library (using cmake + make)"; \
	if [ ! -f src/lapack/build/lib/liblapack.a ]; then cd src/lapack/build; cmake .. > /dev/null 2>&1; make all -j4 > /dev/null 2>&1; cd ../../.. ; fi; \
	echo "[ 20%] Building **proteinortho_clustering** with LAPACK (dynamic linking)"; \
	$(CPP) -std=c++11 -Wall -O3 -fopenmp -flto $(LDFLAGS) -o $@ $< -Isrc/lapack/build/include/ -Lsrc/lapack/build/lib/ -llapack -lblas -I$(INCLUDE_PATH) -L$(LIBRARY_PATH) -lgfortran; )
endif
endif
ifeq ($(USELAPACK),FALSE)
	@echo "[ 20%] Building **proteinortho_clustering** WITHOUT(!) LAPACK";
	@$(CPP) -std=c++11 -Wall -O3 -fopenmp $(LDFLAGS) -o $@ src/proteinortho_clustering_nolapack.cpp -static && ([ $$? -eq 0 ] ) || ( \
		echo "......$(ORANGE)static linking failed of proteinortho_clustering_nolapack, now i switch to dynamic linking.$(NC)"; \
		$(CPP) -std=c++11 -Wall -O3 -fopenmp $(LDFLAGS) -o $@ src/proteinortho_clustering_nolapack.cpp && echo "......OK dynamic linking was successful for proteinortho_clustering_nolapack!"; )
endif

$(BUILDDIR)/cleanupblastgraph: src/cleanupblastgraph.cpp
	$(dir_guard)
	@echo "[ 50%] Building **cleanupblastgraph**"
	@$(CPP) -std=c++11 $(CPPFLAGS) $(LDFLAGS) -o $@ $< -static && ([ $$? -eq 0 ] ) || ( \
		echo "......$(ORANGE)static linking failed of cleanupblastgraph, now i switch to dynamic linking.$(NC)"; \
		$(CPP) $(CPPFLAGS) $(LDFLAGS) -o $@ $< && echo "......OK dynamic linking was successful of cleanupblastgraph!"; )

$(BUILDDIR)/graphMinusRemovegraph: src/graphMinusRemovegraph.cpp
	$(dir_guard)
	@echo "[ 25%] Building **graphMinusRemovegraph**"
	@$(CPP) $(CPPFLAGS) $(LDFLAGS) -o $@ $< -static && ([ $$? -eq 0 ] ) || ( \
		echo "......$(ORANGE)static linking failed of graphMinusRemovegraph, now i switch to dynamic linking.$(NC)"; \
		$(CPP) $(CPPFLAGS) $(LDFLAGS) -o $@ $< && echo "......OK dynamic linking was successful of graphMinusRemovegraph!"; )

$(BUILDDIR)/po_tree: src/po_tree.c
	$(dir_guard)
	@echo "[ 75%] Building **po_tree**"
	@$(CPP) $(CPPFLAGS) -o $@ $< -static && ([ $$? -eq 0 ] ) || ( \
		echo "......$(ORANGE)static linking failed of po_tree, now i switch to dynamic linking.$(NC)"; \
		$(CPP) $(CPPFLAGS) $(LDFLAGS) -o $@ $< && echo "......OK dynamic linking was successful of po_tree!"; )

install: proteinortho6.pl proteinortho $(BUILDDIR)/do_mcl.pl $(BUILDDIR)/po2html.pl $(BUILDDIR)/proteinortho2xml.pl $(BUILDDIR)/proteinortho_clustering $(BUILDDIR)/proteinortho_singletons.pl $(BUILDDIR)/ffadj_mcs.py $(BUILDDIR)/po2tree.pl $(BUILDDIR)/cleanupblastgraph $(BUILDDIR)/graphMinusRemovegraph $(BUILDDIR)/po_tree src/grepfasta.pl
	@echo "INSTALLING everything to $(INSTALLDIR)"
	@install -v $^ $(INSTALLDIR);
	@echo "$(GREEN)Everything installed successfully to $(INSTALLDIR).$(NC)"
	@echo "If needed you can add $(INSTALLDIR) to \$$PATH with 'export PATH=\$$PATH:$(INSTALLDIR)'." 

test: proteinortho6.pl test_step2 test_step3 test_clean
	@echo "[TEST] All tests $(GREEN)passed$(NC)"	

test_step2: proteinortho6.pl
	@echo "[TEST] 1. basic proteinortho6.pl -step=2 test. (algorithms that are not present are skipped)"	
	@echo -n " [1/11] -p=blastp+ test: "
	@if [ "$(shell which blastp)" = "" ]; then\
		echo "$(ORANGE)blastp missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_blastp -p=blastp+ test/*.faa; \
		set -e ; ./src/chk_test.pl test_blastp.proteinortho.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [2/11] -p=blastp+ synteny (PoFF) test: "
	@if [ "$(shell which blastp)" = "" ]; then\
		echo "$(ORANGE)blastp missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_synteny -synteny -singles -p=blastp+ test/*.faa; \
		set -e ; ./src/chk_test.pl test_synteny.proteinortho.tsv; \
		set -e ; ./src/chk_test.pl test_synteny.poff.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [3/11] -p=diamond test: "
	@if [ "$(shell which diamond)" = "" ]; then\
		echo "$(ORANGE)diamond missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_diamond -p=diamond test/*.faa; \
		set -e ; ./src/chk_test.pl test_diamond.proteinortho.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [4/11] -p=diamond (--moresensitive) test (subpara): "
	@if [ "$(shell which diamond)" = "" ]; then\
		echo "$(ORANGE)diamond missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_diamondmoresensitive -p=diamond -subpara="--more-sensitive" test/*.faa; \
		set -e ; ./src/chk_test.pl test_diamondmoresensitive.proteinortho.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [5/11] -p=lastp (lastal) test: "
	@if [ "$(shell which lastal)" = "" ]; then\
		echo "$(ORANGE)lastal missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_lastp -p=lastp test/*.faa; \
		set -e ; ./src/chk_test.pl test_lastp.proteinortho.tsv ; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [6/11] -p=topaz test: "
	@if [ "$(shell which topaz)" = "" ]; then\
		echo "$(ORANGE)topaz missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_topaz -p=topaz test/*.faa; \
		set -e ; ./src/chk_test.pl test_topaz.proteinortho.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [7/11] -p=usearch test: "
	@if [ "$(shell which usearch)" = "" ]; then\
		echo "$(ORANGE)usearch missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_usearch -p=usearch test/*.faa; \
		set -e ; ./src/chk_test.pl test_usearch.proteinortho.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [8/11] -p=ublast test: "
	@if [ "$(shell which usearch)" = "" ]; then\
		echo "$(ORANGE)usearch missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_ublast -p=ublast test/*.faa; \
		set -e ; ./src/chk_test.pl test_ublast.proteinortho.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [9/11] -p=rapsearch test: "
	@if [ "$(shell which rapsearch)" = "" ]; then\
		echo "$(ORANGE)rapsearch missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_rapsearch -p=rapsearch test/*.faa; \
		set -e ; ./src/chk_test.pl test_rapsearch.proteinortho.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [10/11] -p=blatp (blat) test: "
	@if [ "$(shell which blat)" = "" ]; then\
		echo "$(ORANGE)blat missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_blatp -p=blatp test/*.faa; \
		set -e ; ./src/chk_test.pl test_blatp.proteinortho.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

	@echo -n " [11/11] -p=mmseqsp (mmseqs) test: "
	@if [ "$(shell which mmseqs)" = "" ]; then\
		echo "$(ORANGE)mmseqs missing, skipping...$(NC)"; \
	else \
		./proteinortho6.pl -silent -force -project=test_mmseqsp -p=mmseqsp test/*.faa; \
		set -e ; ./src/chk_test.pl test_blatp.proteinortho.tsv; \
		echo "$(GREEN)passed$(NC)"; \
	fi

test_step3: proteinortho6.pl test_step2
	@echo "[TEST] 2. -step=3 tests (src/proteinortho_clustering) "
	@echo -n " [1/2] various test functions of src/proteinortho_clustering (-test): "; \
	$(BUILDDIR)/proteinortho_clustering -test> /dev/null 2>&1
	@echo "$(GREEN)passed$(NC)"
	@echo -n " [2/2] Compare results of 'with lapack' and 'without lapack': "; \
	$(BUILDDIR)/proteinortho_clustering -epsilon 0 test_blastp.blast-graph> /dev/null 2>&1; \
	sort remove.graph -o test.A> /dev/null 2>&1; \
	$(BUILDDIR)/proteinortho_clustering -epsilon 0 -lapack 0 test_blastp.blast-graph> /dev/null 2>&1; \
	sort remove.graph -o test.B> /dev/null 2>&1; \
	set -e ; diff test.A test.B;
	@echo "$(GREEN)passed$(NC)"

test_clean: 
	@echo "[TEST] Clean up all test files..."; \
	rm -rf proteinortho_cache_test_* test.* test_* test/C.faa.* test/E.faa.* test/C2.faa.* test/L.faa.* test/M.faa.*> /dev/null 2>&1;

clean: 
	rm -rf src/BUILD test/C.faa.* test/E.faa.* test/C2.faa.* test/L.faa.* test/M.faa.*
	rm -rf src/lapack/


