PACKAGE_NAME:=makegobbler
SHELL:=bash
DOC:=$(PACKAGE_NAME)-doc
SVN?=svn
STYFILES:=$(PACKAGE_NAME).sty
DOCSRC:=$(DOC).tex
SRC:=$(addprefix doc/latex/$(PACKAGE_NAME)/,$(DOCSRC)) $(addprefix tex/latex/$(PACKAGE_NAME)/,$(STYFILES))
TEXMF_INSTALL_DIR?=$(HOME)/texmf
DISTTYPE?=flat
VALID_DISTTYPES:=dtx flat tds dtx+tds flat+tds plain
# Control sanitaire
ifeq ($(filter-out $(DISTTYPE),$(VALID_DISTTYPES)),$(VALID_DISTTYPES))
$(error DISTTYPE invalide, les valeurs possible sont : $(VALID_DISTTYPES))
endif
DISTDIR:=dist/$(DISTTYPE)
RELROOT:=$(shell realpath --relative-to $(DISTDIR) .)
# 1b1b = 1branche + 1branche
TESTS:=incond ifthen 1,1b 1,2b 2,1b1b 2,2b1b 2,1b2b 2,2b2b
TEST_SERIES:=pdftest
PDFTEST:=test/pdftest
READMESRC:=README.org
README:=$(addprefix $(DISTDIR)/,$(patsubst %.org,%.md,$(READMESRC)))
REFERENCE:=test/reference
TEST_SUBDIR:=$(patsubst %,test/%s,$(TEST_SERIES)) $(REFERENCE)s-text
SUBDIR:=$(TEST_SUBDIR) $(addprefix dist/,$(VALID_DISTTYPES))
DASHES:='=================================================================================================='
TEST_DEPS:=test.cls $(PACKAGE_NAME).sty
EMACS?=emacs

SHELL_ESC=$(subst ','\'',$(1))#'
define PERL_FILE_LIST
use strict;
use warnings;
open(PIPE,"-|","$(SVN)",qw(list --depth infinity)) or die "Ouverture pipeline svn list";
my @list;
while(<PIPE>) {
    s![\r\n]+$$!!;
   unless (-d $$_) {
      push @list, $$_;
   }
}
close(PIPE);
say STDOUT join " ",@list;
endef

INSTALL_DEP:=$(DISTDIR)/$(PACKAGE_NAME).zip \
	$(TEXMF_INSTALL_DIR)/tex/latex/$(PACKAGE_NAME)\
	$(TEXMF_INSTALL_DIR)/doc/latex/$(PACKAGE_NAME)

.PHONY: dist
dist: $(DISTDIR)/$(PACKAGE_NAME)$(filter .tds,.$(DISTTYPE)).zip

# Collecte la liste des sources seulement dans les cas flat, tds ou plain.
ifneq ($(filter $(DISTTYPE),flat tds plain), flat tds plain)
FILE_LIST:=$(shell perl -e '$(call SHELL_ESC,$(PERL_FILE_LIST))')
endif

$(README): README.org
	"$(EMACS)" -Q --file $< --eval "(progn  (org-md-export-to-markdown) (save-buffers-kill-terminal))"
	mv README.md $@

define plus_tds
$(DISTDIR)/$(PACKAGE_NAME).zip: dist/$(1)/$(PACKAGE_NAME).zip dist/tds/$(PACKAGE_NAME).tds.zip $(DISTDIR)/.dir
	cd $(DISTDIR) \
	&& if [ ! -h $(PACKAGE_NAME) ]; then ln -s . $(PACKAGE_NAME); fi \
	&& cp ../$(1)/$(PACKAGE_NAME).zip $(PACKAGE_NAME) \
	&& ln -fs ../tds/$(PACKAGE_NAME).tds.zip $(PACKAGE_NAME).tds.zip \
	&& zip -u $(PACKAGE_NAME).zip $(PACKAGE_NAME)/$(PACKAGE_NAME).tds.zip

dist/$(1)/$(PACKAGE_NAME).zip: $(SRC)
	$(MAKE) dist DISTTYPE=$(1)

dist/tds/$(PACKAGE_NAME).tds.zip: $(SRC)
	$(MAKE) dist DISTTYPE=tds

endef

ifeq ($(DISTTYPE), dtx)
# Distribution de type dtx
# ================================================================================
$(DISTDIR)/$(PACKAGE_NAME).zip: $(DISTDIR)/$(PACKAGE_NAME).dtx $(DISTDIR)/$(PACKAGE_NAME).ins $(DISTDIR)/$(DOC).pdf $(README)
	cd $(DISTDIR) \
	&& if [ ! -h $(PACKAGE_NAME) ]; then ln -s . $(PACKAGE_NAME); fi \
	&& zip $(notdir $@) $(addprefix $(PACKAGE_NAME)/, $(notdir $^))

$(DISTDIR)/$(DOC).pdf: $(DISTDIR)/$(PACKAGE_NAME).dtx
	cd $(DISTDIR) && latexmk -jobname=$(DOC) -pdf $(PACKAGE_NAME).dtx

$(addprefix $(DISTDIR)/,$(STYFILES)): $(DISTDIR)/$(PACKAGE_NAME).dtx $(DISTDIR)/$(PACKAGE_NAME).ins
	cd $(DISTDIR) && pdftex $(PACKAGE_NAME).ins

$(DISTDIR)/$(PACKAGE_NAME).dtx $(DISTDIR)/$(PACKAGE_NAME).ins: $(DISTDIR)/.dir tex/latex/$(PACKAGE_NAME)/$(PACKAGE_NAME).sty doc/latex/$(PACKAGE_NAME)/$(DOC).tex
	cd $(DISTDIR) && makedtx -dir $(RELROOT)/tex/latex/$(PACKAGE_NAME) -src '$(PACKAGE_NAME)\.sty$$=>$(PACKAGE_NAME).sty' -doc '$(RELROOT)/doc/latex/$(PACKAGE_NAME)/$(DOC).tex' -codetitle "Le code" -author 'Vincent Bela{\"\i}che' $(PACKAGE_NAME)

else
$(DISTDIR)/$(DOC).pdf: $(DISTDIR)/.dir dist/dtx/$(DOC).pdf
	cd $(DISTDIR) && ln ../dtx/$(DOC).pdf $(DOC).pdf

dist/dtx/$(DOC).pdf: $(SRC)
	$(MAKE) doc DISTTYPE=dtx

$(addprefix dist/dtx/,$(STYFILES)): $(addprefix tex/latex/$(PACKAGE_NAME)/,$(STYFILES))
	$(MAKE) $@ DISTTYPE=dtx

ifeq ($(DISTTYPE), plain)
# Distribution de type plain
# ================================================================================
# On zippe juste toutes les sources + la doc compilée
$(DISTDIR)/$(PACKAGE_NAME).zip: $(DISTDIR)/$(DOC).pdf $(FILE_LIST)
	cd $(DISTDIR) && zip $(notdir $@) $(DOC).pdf
	zip $@ $(patsubst %,'%',$(FILE_LIST))
else ifeq ($(DISTTYPE), tds)
# Distribution de type tds
# ================================================================================
$(DISTDIR)/$(PACKAGE_NAME).tds.zip: $(addprefix $(DISTDIR)/doc/latex/$(PACKAGE_NAME)/,$(DOC).pdf $(DOCSRC)) \
	$(addprefix $(DISTDIR)/tex/latex/$(PACKAGE_NAME)/,$(STYFILES)) $(FILE_LIST) \
	$(DISTDIR)/source/latex/$(PACKAGE_NAME)
	cd $(DISTDIR) && zip $(PACKAGE_NAME).tds.zip \
		$(addprefix doc/latex/$(PACKAGE_NAME)/,$(DOC).pdf $(DOCSRC)) \
		$(addprefix tex/latex/$(PACKAGE_NAME)/,$(STYFILES)) \
		$(patsubst %,'%',$(addprefix source/latex/$(PACKAGE_NAME)/, $(FILE_LIST)))

$(DISTDIR)/doc/latex/$(PACKAGE_NAME)/$(DOC).pdf: dist/dtx/$(DOC).pdf $(DISTDIR)/doc/latex/$(PACKAGE_NAME)
	cd $(dir $@) && ln -s $(RELROOT)/../../../$< $(notdir $@)

$(addprefix $(DISTDIR)/doc/latex/$(PACKAGE_NAME)/,$(DOCSRC)):$(DISTDIR)/doc/latex/$(PACKAGE_NAME)/%.tex: doc/latex/$(PACKAGE_NAME)/%.tex $(DISTDIR)/doc/latex/$(PACKAGE_NAME)
	cd $(dir $@) && ln -s $(RELROOT)/../../../$< $(notdir $@)

$(addprefix $(DISTDIR)/tex/latex/$(PACKAGE_NAME)/,$(STYFILES)):$(DISTDIR)/tex/latex/$(PACKAGE_NAME)/%: dist/dtx/% $(DISTDIR)/tex/latex/$(PACKAGE_NAME)
	cd $(dir $@) && ln -s $(RELROOT)/../../../$< $(notdir $@)

$(DISTDIR)/doc/latex/$(PACKAGE_NAME):
	mkdir -p $@

$(DISTDIR)/tex/latex/$(PACKAGE_NAME):
	mkdir -p $@

$(DISTDIR)/source/latex/$(PACKAGE_NAME):
	mkdir -p $(dir $@)
	cd $(dir $@) && ln -s ../../$(RELROOT) $(PACKAGE_NAME)
else ifeq ($(DISTTYPE), flat)
# Distribution de type flat
# ================================================================================
$(DISTDIR)/$(PACKAGE_NAME).zip: dist/dtx/$(PACKAGE_NAME).zip $(DISTDIR)/.dir $(FILE_LIST)
	cd $(DISTDIR) \
	&& if [ ! -h $(PACKAGE_NAME) ]; then ln -s . $(PACKAGE_NAME); fi \
	&& cp ../dtx/$(PACKAGE_NAME).zip $(PACKAGE_NAME) \
	&& if [ ! -h source ]; then ln -s $(RELROOT) source; fi \
	&& zip $(notdir $@) $(patsubst %,'$(PACKAGE_NAME)/source/%',$(FILE_LIST))

dist/dtx/$(PACKAGE_NAME).zip: $(SRC)
	$(MAKE) dist DISTTYPE=dtx

else ifeq ($(DISTTYPE), dtx+tds)
# Distribution de type dtx+tds
# ================================================================================
$(eval $(call plus_tds,dtx))
else ifeq ($(DISTTYPE), flat+tds)
# Distribution de type flat+tds
# ================================================================================
$(eval $(call plus_tds,flat))
else
$(error Type de distribution $(DISTTYPE) non pris en charge)
endif
endif

.PHONY: pdf doc
pdf doc: $(DISTDIR)/$(DOC).pdf

.PHONY: distclean
distclean:
	rm -fr $(DISTDIR)

.PHONY: distrealclean
distrealclean:
	$(foreach DISTTYPE,$(VALID_DISTTYPES),$(MAKE) distclean DISTTYPE=$(DISTTYPE);)

.PHONY: install
install: install$(DISTTYPE)

$(TEXMF_INSTALL_DIR)/tex/latex/$(PACKAGE_NAME):
	mkdir -p $@

$(TEXMF_INSTALL_DIR)/doc/latex/$(PACKAGE_NAME):
	mkdir -p $@

.PHONY: installdtx
installdtx: $(INSTALL_DEP) $(addprefix $(DISTDIR)/,$(DOC).pdf $(STYFILES))
	for w in $(addprefix $(DISTDIR)/,$(DOC).pdf); \
		do cp $$w $(TEXMF_INSTALL_DIR)/doc/latex/$(PACKAGE_NAME); \
		done
	for w in $(addprefix $(DISTDIR)/,$(STYFILES)); \
		do cp $$w $(TEXMF_INSTALL_DIR)/tex/latex/$(PACKAGE_NAME); \
		done

# Installation danes les cas
define _1
.PHONY: $(1)
$(1): installdtx

endef
$(foreach DT, flat tds dtx+tds flat+tds,$(eval $(call _1,$(DT))))

.PHONY: test
test: pdftest

define ERROR_COUNT_AWK
BEGIN { failcount=0} ;\
/^Test [^:]+: failed/ { ++failcount } ;\
END   { print "\nTotal failure count = " failcount}
endef

.PHONY: total_pdftests
total_pdftests: $(patsubst %,$(PDFTEST)s/test-%.txt,$(TESTS))
	awk '$(ERROR_COUNT_AWK)' $(PDFTEST)s.log >> $(PDFTEST)s.log
	@echo $(DASHES)
	@echo '== End target pdftests'
	@echo $(DASHES)

define _1
.PHONY: textdiff-$(1)
textdiff-$(1): $(PDFTEST)s/test-$(1).txt $(REFERENCE)s-text/test-$(1).txt echo_pdftest
	if diff -abs $(PDFTEST)s/"test-$(1).txt" $(REFERENCE)s-text/"test-$(1).txt"; then \
		echo "Test $(1): ok" >> $(PDFTEST)s.log; \
	else echo "Test $(1): failed = différent de la référence" >> $(PDFTEST)s.log; \
	fi

$(PDFTEST)s/test-$(1).txt:$(PDFTEST)s/test-$(1).pdf $(addprefix $(PDFTEST)s/,$(TEST_DEPS))
	pdftotext "$$<" "$$@"

$(REFERENCE)s-text/$(1).txt:$(REFERENCE)s-text/$(1).pdf $(addprefix $(REFERENCE)s-text/,$(TEST_DEPS))
	pdftotext "$$<" "$$@"

endef
$(eval $(foreach TEST,$(TESTS),$(call _1,$(TEST))))

$(patsubst %,$(PDFTEST)s/test-%.pdf,$(TESTS)):$(PDFTEST)s/test-%.pdf: test/test-%.tex  $(INSTITUT_%) $(addprefix $(PDFTEST)s/,$(TEST_DEPS)) $(PDFTEST_PHONY_DEPS)
	cd $(PDFTEST)s/; \
	echo $(patsubst %,$(notdir $<).%,$(CLEAN_EXT)) | xargs rm -f; \
	cmd="pdflatex -interaction=nonstopmode "; \
	cmd="$$cmd\\\\input ../\"$(notdir $<)\""; \
	echo "Exécution de : $$cmd."; \
	if eval "$$cmd"; then  :; \
	else echo "Test $*: failed = échec compilation, état de sortie = $$?" >> ../$(notdir $(PDFTEST)s.log); exit $$?; \
	fi


$(patsubst %,$(REFERENCE)s-text/test-%.txt,$(TESTS)):$(REFERENCE)s-text/test-%.txt: $(REFERENCE)s-text/test-%.pdf
	pdftotext "$<" "$@"

$(patsubst %,$(REFERENCE)s-text/test-%.pdf,$(TESTS)):$(REFERENCE)s-text/test-%.pdf: $(REFERENCE)s/test-%.tex $(addprefix $(REFERENCE)s-text/,$(TEST_DEPS))
	cd $(REFERENCE)s-text/; \
	echo $(patsubst %,$(notdir $<).%,$(CLEAN_EXT)) | xargs rm -f; \
	cmd="pdflatex -interaction=nonstopmode "; \
	cmd="$$cmd\\\\input ../$(notdir $(REFERENCE)s)/\"$(notdir $<)\""; \
	echo "Exécution de : $$cmd."; \
	if eval "$$cmd"; then  :; \
	else echo "Test $*: failed = échec compilation, état de sortie = $$?" >> ../$(notdir $(REFERENCE)s.log); \
	fi

define TOTAL_FAILURE_COUNT_AWK
BEGIN { tfc=0; found=0}; \
/Total failure count = / && found == 1 { print "Deux occurrences de \"Total failure count\" dans le log " FILENAME; exit(-1); }; \
/Total failure count = / && found == 0 { split($$0,a," *= *"); tfc += a[2]; found = 1}; \
END { print tfc}
endef

# Création répertoires
define _1
$(1)/.dir:
	mkdir -p $(1)
	touch $$@

endef
$(eval $(foreach TARGET,$(SUBDIR),$(call _1,$(TARGET))))

# Création liens sur extensions pour compiler les tests
define _1
$(1)/test.cls: $(1)/.dir test/test.cls
	cd $(1) && if [ ! -h test.cls ]; then ln -s ../test.cls test.cls; fi

$(1)/$(PACKAGE_NAME).sty: $(1)/.dir tex/latex/$(PACKAGE_NAME)/$(PACKAGE_NAME).sty
	cd $(1) && if [ ! -h $(PACKAGE_NAME).sty ]; then ln -s ../../tex/latex/$(PACKAGE_NAME)/$(PACKAGE_NAME).sty $(PACKAGE_NAME).sty; fi

endef
$(eval $(foreach TARGET,$(TEST_SUBDIR),$(call _1,$(TARGET))))

$(PDFTEST)s.log:  $(patsubst %,textdiff-%,$(TESTS)) total_pdftests

define _1
.PHONY: echo_$(1)
echo_$(1):
	rm -f $(1)s.log
	@echo $(DASHES)
	@echo '== Début cible $(1)'
	@echo $(DASHES)

.PHONY: $(1)
$(1):  test/$(1)s.log
	@declare -i failure_count=$$$$(awk '$$(TOTAL_FAILURE_COUNT_AWK)' $$<); \
	echo $(DASHES);\
	echo "== $(1) TOTAL FAILURE COUNT = $$$$failure_count"; \
	if [ $$$$failure_count -ne 0 ]; then \
		echo "== ERROR: please correct failed test(s) before commiting changes"; \
		echo $(DASHES);\
		exit -1; \
	fi;\
	echo $(DASHES)

endef

$(eval $(foreach TARGET,$(TEST_SERIES),$(call _1,$(TARGET))))

.PHONY: testclean
testclean:
	$(foreach S,$(SUBDIR), rm -fr $(S);)
	$(foreach S,$(TEST_SERIES), rm -f test/$(S)s.log;)

.PHONY: help
help:
	@echo 'Cibles du projet :'
	@echo
	@echo 'dist : construit la distribution'
	@echo '       utilisez la variable DISTTYPE pour préciser le type de distribution,'
	@echo '       valeurs prises en charges :'
	@echo '       - dtx : fichiers .ins, .dtx, README et manuel seulement'
	@echo '       - flat : pareil que dtx, mais en plus le .zip contient les sources'
	@echo '       - tds : fichier .tds.zip, même contenu que dtx mais avec la disposition'
	@echo '               TDS et le code source en plus'
	@echo '       - dtx+tds : pareil que dtx, mais avec le .tds.zip en plus'
	@echo '       - flat+tds : pareil que flat, mais avec le .tds.zip en plus'
	@echo '       - plain : juste le code source'
	@echo 'distclean: nettoie les produits'
	@echo 'distrealclean: nettoie les produits qq soit le type de distribution'
	@echo 'doc  : compile le manuel'
	@echo 'install: installe à partir des sources. La variable d’environnement '
	@echo '       TEXMF_INSTALL_DIR permet de configurer le répertoire TEXMF visé'
	@echo 'help : produit ce message d’aide'
	@echo 'pdf  : pareil que doc'
	@echo 'test : fait tourner les essais'
	@echo 'testclean : Efface les résultats d’essais'

# Local Variables:
# coding: utf-8
# End:
