############# Names and dirs #############

SONAME = libPsySystem$(EXT).so
PY2SONAME = libPsyPython2Link$(EXT).so
PY3SONAME = libPsyPython3Link$(EXT).so

BINDIR = bin
SRCDIR = src
BUILDDIR = build$(EXTLOW)

INCLUDEDIRS = include ../CMSDK/include
LIBRARIES = ../CMSDK/lib/arch/libCMSDK$(EXT).a
PY2INCLUDEDIRS = $(PYTHON2INCLUDE) -I../CMSDK/src
PY3INCLUDEDIRS = $(PYTHON3INCLUDE) -I../CMSDK/src


############# Include system stuff #############

include ../CMSDK/Makefile.sys

############# Files to compile #############

CPPFILES =  Catalog.cpp PsySystem.cpp Stream.cpp Whiteboard.cpp
CPPFILES += MessageDataCatalog.cpp TimeSeriesCatalog.cpp TaskManagerCatalog.cpp
CPPFILES += CCMCatalog.cpp ControlPanel.cpp
PY2CPPFILES =  Python2Link.cpp
PY3CPPFILES =  Python3Link.cpp


############# Setup dirs #############

SO = $(BINDESTDIR)/$(SONAME)
PY2SO = $(BINDESTDIR)/$(PY2SONAME)
PY3SO = $(BINDESTDIR)/$(PY3SONAME)

SRCFILES = $(patsubst %.cpp,$(SRCDIR)/%.cpp,$(CPPFILES))
OBJFILES = $(patsubst %.cpp,$(BUILDDIR)/%.o,$(CPPFILES))
PY2SRCFILES = $(patsubst %.cpp,$(SRCDIR)/%.cpp,$(PY2CPPFILES))
PY3SRCFILES = $(patsubst %.cpp,$(SRCDIR)/%.cpp,$(PY3CPPFILES))
PY2OBJFILES = $(patsubst %.cpp,$(BUILDDIR)/%.op2,$(PY2CPPFILES))
PY3OBJFILES = $(patsubst %.cpp,$(BUILDDIR)/%.op3,$(PY3CPPFILES))

INCLUDES = $(patsubst %,-I% ,$(INCLUDEDIRS)) $(OPENSSL_CFLAGS)
LIBS = $(subst /arch/,/$(ARCH)/,$(LIBRARIES))

# Python3Link.cpp does #include "cmsdk3[debug]_wrap.cxx", resolved from
# -I../CMSDK/src. The committed CMSDK wrapper is LP64/Linux-flavoured; on macOS/
# Windows it won't compile (see CMSDK/Makefile.sys SWIGWORDFLAG note). When swig
# is available, regenerate the OS-correct wrapper into our build dir and prepend
# it to the include path so the #include picks it up instead of the tracked
# src/ copy — leaving the tracked file untouched. When swig is absent, WRAP3GEN/
# WRAP3INCLUDE are empty and the build uses the committed wrapper (unchanged
# Linux/Windows behaviour). CMSDK_WRAP_SRC is the cmsdk.i the wrapper derives from.
CMSDK_WRAP_SRC = ../CMSDK/cmsdk.i
ifneq ($(SWIG_AVAILABLE),)
  WRAP3GEN = $(BUILDDIR)/cmsdk3$(EXTLOW)_wrap.cxx
  WRAP3INCLUDE = -I$(BUILDDIR)
else
  WRAP3GEN =
  WRAP3INCLUDE =
endif

RESULT := $(shell if [ ! -d $(BINDIR) ]; then mkdir $(BINDIR); fi)
RESULT := $(shell if [ ! -d $(BINDESTDIR) ]; then mkdir $(BINDESTDIR); fi)
RESULT := $(shell if [ ! -d $(BUILDDIR) ]; then mkdir $(BUILDDIR); fi)

############# Overall commands #############

all : $(SO)
	@echo $(SO) ready

debug: all

profile: all

ssl: all

ssldebug: all

python2: $(PY2SO)

python3: $(PY3SO)

############# Dependencies #############

$(BUILDDIR)/%.d: $(SRCDIR)/%.cpp
	@echo Making dependencies for $(<F)...
	@$(SHELL) -ec '$(CC) -MM $(INCLUDES) -D $(SYSTEM) $(STANDARD) $< \
		| sed '\''s/\($(*F)\)\.o[ :]*/\1.o $(@F) : /g'\'' > $@; \
		[ -s $@ ] || rm -f $@'

ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),cleandebug)
ifneq ($(MAKECMDGOALS),totalclean)
ifneq ($(MAKECMDGOALS),python2)
ifneq ($(MAKECMDGOALS),python3)
  -include $(OBJFILES:.o=.d)
endif
endif
endif
endif
endif

############# Compiling #############

$(BUILDDIR)/%.o: $(SRCDIR)/%.cpp
	@mkdir -p $(@D)
	@echo Compiling $(<F)
	@$(CC) $(DEBUG) $(INCLUDES) $(STANDARD) $(NOTLINK) $(OUTPUT_OPTION) $<

$(BUILDDIR)/%.op2: $(SRCDIR)/%.cpp
	@mkdir -p $(@D)
	@echo Compiling $(<F)
	@$(CC) $(DEBUG) $(INCLUDES) $(PY2INCLUDEDIRS) $(STANDARD) $(NOTLINK) $(OUTPUT_OPTION) $<

$(BUILDDIR)/%.op3: $(SRCDIR)/%.cpp $(WRAP3GEN)
	@mkdir -p $(@D)
	@echo Compiling $(<F)
	@$(CC) $(DEBUG) $(INCLUDES) $(WRAP3INCLUDE) $(PY3INCLUDEDIRS) $(STANDARD) $(NOTLINK) $(OUTPUT_OPTION) $<

# Generate the OS-correct SWIG wrapper Python3Link.cpp #includes. The module
# name must match the #include: cmsdk3_wrap.cxx (release) / cmsdk3debug_wrap.cxx
# (debug), selected by $(EXTLOW). Only used when swig is available.
ifneq ($(SWIG_AVAILABLE),)
$(WRAP3GEN): $(CMSDK_WRAP_SRC)
	@mkdir -p $(@D)
	@echo Generating OS-correct SWIG wrapper $(@F) ...
	@$(SWIG) -c++ -python $(SWIGWORDFLAG) -module cmsdk3$(EXTLOW) -I../CMSDK/include -outdir $(BUILDDIR) -o $@ $(CMSDK_WRAP_SRC)
endif

############# Linking #############

$(SO): $(OBJFILES) $(LIBS)
	@echo Linking $(SO) $(SYSTEM)...
	@$(CC) $(DEBUG) $(STANDARD) $(LIBOPT) $(OBJFILES) $(LIBPATHS) $(OPENSSL_LDFLAGS) -o $(SO) $(LIBS) $(OTHERLIBS)

$(PY2SO): $(PY2OBJFILES) $(LIBS)
	@echo Linking $(PY2SO) $(SYSTEM)...
	$(CC) $(DEBUG) $(STANDARD) $(LIBOPT) $(LIBPATHS) $(OPENSSL_LDFLAGS) $(PY2OBJFILES) -o $(PY2SO) $(LIBS) $(PYTHON2LIB) $(OTHERLIBS)

$(PY3SO): $(PY3OBJFILES) $(LIBS)
	@echo Linking $(PY3SO) $(SYSTEM)...
	@$(CC) $(DEBUG) $(STANDARD) $(LIBOPT) $(LIBPATHS) $(OPENSSL_LDFLAGS) $(PY3OBJFILES) -o $(PY3SO) $(LIBS) $(PYTHON3LIB) $(OTHERLIBS)

############# Cleaning #############

clean:
	@echo Removing .o files and executable
	@find $(BUILDDIR) -path '*/.svn' -prune -o -type f -name \*.[o,d]\* -exec rm -f {} \;
	@rm -rf $(BUILDDIR)
	@rm -f $(SO)
	@rm -f $(PY2SO)
	@rm -f $(PY3SO)
	@make cleandebug

cleandebug:
	@echo Removing debug .o files and executable
	@find $(BUILDDIR) -path '*/.svn' -prune -o -type f -name \*.[o,d]\* -exec rm -f {} \;
	@rm -rf $(BUILDDIR)
	@rm -f $(SO)
	@rm -f $(PY2SO)
	@rm -f $(PY3SO)
	
totalclean : clean
	#@echo Code size before is: `du -ks .`
	@echo Cleaning Visual Studio files...
	@rm -f *.lib
	@find . -type d -name Debug -exec rm -rf {} \; > /dev/null 2>&1
	@find . -type d -name Release -exec rm -rf {} \; > /dev/null 2>&1
	@find . -type f -name \*.ncb -exec rm -f {} \; > /dev/null 2>&1
	@find . -type f -name \*.plg -exec rm -f {} \; > /dev/null 2>&1
	@find . -type f -name \*.exe -exec rm -f {} \; > /dev/null 2>&1
	@find . -type f -name \*.ilk -exec rm -f {} \; > /dev/null 2>&1
	@find . -type f -name \*.vcl -exec rm -f {} \; > /dev/null 2>&1
	@echo Cleaning core dump files...
	@find . -type f -name core -exec rm -f {} \; > /dev/null 2>&1
	#@echo Code size after is: `du -ks .`

############# Additional commands #############

rebuild : clean all
