##
## Variables
##

DALIDOC?=.
DALIDOC_SOURCE_DIR?=.
DALIDOC_BUILD_DIR?=.
DALIDOC_MEDIAS_DIR?=medias

DALIDOC_VERSION:=$(shell git -C $(DALIDOC) symbolic-ref -q --short HEAD || git -C $(DALIDOC) describe --tags --exact-match)

DALIDOC_LATEST_TAG_ON_ORIGIN:=$(shell git -C $(DALIDOC)  -c 'versionsort.suffix=-' ls-remote --exit-code --tags --sort='v:refname' origin | tail -n1 | cut --delimiter='/' --fields=3)

UV_RUN?=uv run --project dalidoc

# Lancer `MKDOCS=mkdocs make portal` pour ne pas utiliser `uv`
MKDOCS?=$(UV_RUN) mkdocs
# Dossier de base portail
MKDOCS_BASE_DIR?=$(DALIDOC)/portal/
# Dossier de customisation du portail
MKDOCS_CUSTOM_DIR?=./portal
# Dossier de fusion entre la base et la customisation
MKDOCS_MERGED_DIR?=$(DALIDOC_BUILD_DIR)/_merged/
# Dossier intermédiaire : stockage des fichiers MD pré-compilés par pandoc
MKDOCS_PREPROCESS_DIR?=$(DALIDOC_BUILD_DIR)/_mkdocs/
# Dossier final
MKDOCS_SITE_DIR?=_site

MD_FOR_MKDOCS?=$(foreach m,$(wildcard $(DALIDOC_SOURCE_DIR)/*.md),$(MKDOCS_PREPROCESS_DIR)/$(notdir $m))

VENV?=.venv

MDL?=$(UV_RUN) rumdl check

# Garder cette cible en haut
default: help

RSYNC=rsync --archive --verbose

##
## Checks
##

.PHONY: check_dalidoc
check_dalidoc: #: Vérifie si le sous-module dalidoc est à jour
ifeq ($(DALIDOC_VERSION), $(DALIDOC_LATEST_TAG_ON_ORIGIN))
	$(info dalidoc est à jour.)
else
	$(info version locale=$(DALIDOC_VERSION))
	$(info dernière version disponible=$(DALIDOC_LATEST_TAG_ON_ORIGIN))
	$(info dalidoc n'est pas à jour !)
	$(info Essayez `git -C $(DALIDOC) fetch --all && git -C $(DALIDOC) checkout $(DALIDOC_LATEST_TAG_ON_ORIGIN)`)
endif


##
## Help
##

help::  #: Affiche cette page
	@echo
	@echo "    dalidoc $(DALIDOC_VERSION)"
	@echo
	@echo "Cibles make disponibles :"
	@echo
	@gawk 'match($$0, /([^:]*):.+#'': (.*)/, m) { printf "    %-16s%s\n", m[1], m[2]}' $(MAKEFILE_LIST) | sort
	@echo


##
## Pandoc
##

# Fichiers préfixe de toutes les docs.
PANDOC_METADATA_FILE?=$(DALIDOC)/config/metadata.yml

# Pour activer/désactiver les filtres pandoc, il suffit de surcharger ou vider
# ces variables dans le Makefile local
#
PANDOC_COVER?=--filter=pandoc-cover
PANDOC_INCLUDE?=--filter=pandoc-include
PANDOC_JINJA?=--filter=pandoc-jinja
PANDOC_LATEX_ENVIRONMENT?=--filter=pandoc-latex-environment

# le filtre pandoc-recap est expérimental
#PANDOC_RECAP?=--filter=pandoc-recap

PANDOC_SYNTAXDEF+=--syntax-definition=$(DALIDOC)/include/highlight/console.xml

# Paramètres pandoc communs à tous les formats d'export
#
# Attention l'ordre des filtres est important !
# Le principe est de déclencher les filtres impactant le fond (include, jinja,
# etc.) en priorité et pour tous les formats.
# Puis déclencher les filtres impactant la forme ( cover, latex-environment,
# etc. ) spécifiquement en fonction du format d'export.
#
PANDOC_ARGS?=--strip-comments \
             --mathml \
             --metadata-file=$(PANDOC_METADATA_FILE) \
             --resource-path=.:`dirname $<`:dalidoc \
             $(PANDOC_SYNTAXDEF) \
             $(PANDOC_INCLUDE) \
             $(PANDOC_JINJA) \
             $(PANDOC_RECAP)

##
## Pandocker
##

# La version de pandocker à utiliser
PANDOCKER_TAG?=stable


# Utile pour tracer un bug latex
#PANDOCKER_ENTRYPOINT?=--entrypoint xelatex

ifeq (0, $(shell grep -q docker  /proc/self/cgroup; echo -n $$?))
# On est dans docker, on utilise directement pandoc
PANDOC=pandoc
else ifdef NO_DOCKER
# On veut utiliser la commande locale
PANDOC=pandoc
else
# Sinon, se replier sur docker
PANDOC:=docker run --rm \
	--user `id -u`:`id -g` \
	--volume $(CURDIR):/pandoc $(PANDOCKER_ENTRYPOINT) \
	dalibo/pandocker:$(PANDOCKER_TAG)
endif

#
# DOCS_SRC est la liste des fichers source Markdown
#
# On inclut tous les fichiers *.md du dossier source
# Sauf:
# - les fichiers qui commencent par '_'
# - les fichiers dans le dossier $DALIDOC
# - les README
#

#DALIDOC_IGNORE_OLDER_THAN?=90
ifdef DALIDOC_IGNORE_OLDER_THAN
  FIND_MTIME=-mtime -$(DALIDOC_IGNORE_OLDER_THAN)
endif

DOCS_SRC?=$(shell find $(DALIDOC_SOURCE_DIR)/* \
                  -name '*.md' \
                  -and ! -path '*/_*' \
                  -and ! -path '$(MKDOCS_CUSTOM_DIR)/*' \
                  -and ! -path '$(DALIDOC)/*' \
                  -and ! -name 'README.md' \
                  $(FIND_MTIME) \
)


##
## Cible globale
##

#DALIDOC_TARGET_FORMATS?= markdown pdf html odt slides epub
DALIDOC_TARGET_FORMATS?= pdf

all: docs

.PHONY: docs
docs: $(DALIDOC_TARGET_FORMATS) #: Génère les formats définis par $DALIDOC_TARGET_FORMATS


##
## EPUB
##
## Pas vraiment testé, on le conserve pour des raisons historiques
##

DOCS_EPUB?=$(DOCS_SRC:.md=.epub)

.PHONY: epub
epub:: $(foreach d,$(DOCS_EPUB),$(DALIDOC_BUILD_DIR)/$(d)) #: Génère les docs au format EPUB

$(DALIDOC_BUILD_DIR)/%.epub:: %.md
	mkdir -p $(dir $@)
	$(PANDOC) \
		$(PANDOC_ARGS) \
		$< -o $@

##
## HTML (avec uikit)
##
## export "monolithique" du document, utile pour les formations
##

DOCS_HTML?=$(DOCS_SRC:.md=.html)

.PHONY: html
html:
	$(info La cible 'make html' est désactivée à partir de dalidoc 5.)
	$(info Utiliser 'make portal' pour générer le portail avec mkdocs.)
	$(info ou 'make pandoc-html' pour génerer l'ancien format html)

.PHONY: pandoc-html
pandoc-html:: $(foreach d,$(DOCS_HTML),$(DALIDOC_BUILD_DIR)/$(d))  #: Génère les docs au format HTML

PANDOC_HTML_TEMPLATE?=uikit

$(DALIDOC_BUILD_DIR)/%.html:: %.md
	mkdir -p $(dir $@)
	$(PANDOC) \
		$(PANDOC_ARGS) \
		--template=$(PANDOC_HTML_TEMPLATE) \
		--toc \
		--css $(DALIDOC)/include/css/dalibo.$(PANDOC_HTML_TEMPLATE).css \
		$< -o $@

##
## Markdown
##
## Si le client demande un export markdown, il vaut mieux envoyer
## une export markdown plutot que le fichier source
##
## On utilise l'extension `.markdown` pour différiencer l'export et la source
##

DOCS_MD?=$(DOCS_SRC:.md=.markdown)

.PHONY: markdown
markdown:: $(foreach d,$(DOCS_MD),$(DALIDOC_BUILD_DIR)/$(d))  #: Génère les docs au format Markdown

$(DALIDOC_BUILD_DIR)/%.markdown:: %.md
	mkdir -p $(dir $@)
	$(PANDOC) \
		$(PANDOC_ARGS) \
		$< -o $@

##
## ODT
##
## Rarement demandé, conservé pour des raisons historiques
##

DOCS_ODT?=$(DOCS_SRC:.md=.odt)

.PHONY: odt
odt:: $(foreach d,$(DOCS_ODT),$(DALIDOC_BUILD_DIR)/$(d))  #: Génère les docs au format ODT

$(DALIDOC_BUILD_DIR)/%.odt:: %.md
	mkdir -p $(dir $@)
	$(PANDOC) \
		$(PANDOC_ARGS) \
		--toc \
		--listings \
		$< -o $@

##
## PDF
##

DOCS_PDF?=$(DOCS_SRC:.md=.pdf)

.PHONY: pdf
pdf:: $(foreach d,$(DOCS_PDF),$(DALIDOC_BUILD_DIR)/$(d))  #: Génère les docs au format PDF

PANDOC_PDF_TEMPLATE?=eisvogel

# L'option --listings n'aime pas les caractères UTF-8 !
# On la désactive par défaut
#PANDOC_PDF_LISTINGS?=--listings

$(DALIDOC_BUILD_DIR)/%.tex $(DALIDOC_BUILD_DIR)/%.pdf:: %.md
	mkdir -p $(dir $@)
	$(PANDOC) \
		$(PANDOC_ARGS) \
		--template=$(PANDOC_PDF_TEMPLATE) \
		--pdf-engine-opt=-shell-escape \
		--pdf-engine=xelatex \
		--toc \
		$(PANDOC_COVER) \
		$(PANDOC_LATEX_ENVIRONMENT) \
		$(PANDOC_PDF_LISTINGS) \
		$< -o $@



##
## Slides HTML avec Revealjs
##
## On utilise l'extension `slides.html` pour différencier avec l'export uikit
##

DOCS_SLIDES?=$(DOCS_SRC:.md=.slides.html)
.PHONY: slides
slides:: $(foreach d,$(DOCS_SLIDES),$(DALIDOC_BUILD_DIR)/$(d))  #: Génère les diapos avec RevealJS

$(DALIDOC_BUILD_DIR)/%.slides.html:: %.md
	mkdir -p $(dir $@)
	$(PANDOC) \
		$(PANDOC_ARGS) \
		--to revealjs \
		--embed-resources \
		--standalone \
		--css $(DALIDOC)/include/css/dalibo.reveal.css \
		$< -o $@

##
## Slides PDF
## Decktape permet de convertir les slides HTML en PDF
##

DECKTAPE?=docker run --rm -u `id -u`:`id -g` --privileged -v $(CURDIR):/slides astefanutti/decktape

DOCS_SLIDES_PDF?=$(DOCS_SRC:.md=.slides.pdf)
.PHONY: slides
slides_pdf:: $(foreach d,$(DOCS_SLIDES_PDF),$(DALIDOC_BUILD_DIR)/$(d))  #: Génère les diapos en PDF

%.slides.pdf: %.slides.html
	mkdir -p $(dir $@)
	$(DECKTAPE) --size 1920x1080 $^ $@

##
## Slides PowerPoint
##

DOCS_SLIDES_PPTX?=$(DOCS_SRC:.md=.slides.pptx)
.PHONY: slides
slides_pptx:: $(foreach d,$(DOCS_SLIDES_PPTX),$(DALIDOC_BUILD_DIR)/$(d))  #: Génère les diapos avec RevealJS

$(DALIDOC_BUILD_DIR)/%.slides.pptx:: %.md
	mkdir -p $(dir $@)
	$(PANDOC) \
		$(PANDOC_ARGS) \
		--reference-doc $(DALIDOC)/include/pptx/styles.pptx \
		$< -o $@


##
## debug
##


DOCS_TEX?=$(DOCS_SRC:.md=.tex)
.PHONY: debug
debug:
	$(info DALIDOC  = $(DALIDOC))
	$(info DALIDOC_TARGET_FORMATS = $(DALIDOC_TARGET_FORMATS))
	$(info DOCS_SRC = $(DOCS_SRC))
	$(info DOCS_PDF = $(DOCS_PDF))

.PHONY: tex
tex:: $(foreach d,$(DOCS_TEX),$(DALIDOC_BUILD_DIR)/$(d))  #: Génère les docs au format TEX (debug)

##
## Mermaid
##


DALIDOC_MERMAID_DIR?=images/mermaid
DALIDOC_MERMAID_OPT?=-t neutral

ifdef NO_DOCKER
# On veut utiliser la commande locale
MERMAID?=mmdc
else
MERMAID?=docker run --rm -u `id -u`:`id -g` -v `pwd`:/data minlag/mermaid-cli:latest
endif

MMD := $(shell test -d $(DALIDOC_MERMAID_DIR) && find $(DALIDOC_MERMAID_DIR) -name '*.md')
SVG = $(MMD:.md=.svg)
PNG = $(MMD:.md=.png)

.PHONY: png svg
mermaid: png svg #: Génère les images dans le dossier $DALIDOC_MERMAID_DIR
png: $(PNG)
svg: $(SVG)

%.png: %.md
	$(MERMAID) $(MERMAID_OPT) -i /data/$^ -o /data/$@

%.svg: %.md
	$(MERMAID) $(MERMAID_OPT) -i /data/$^ -o /data/$@


##
## Lint
##
lint: #: Vérifier la syntax Markdown
	$(MDL) .

##
## Portail
##

# Transformer des fichiers source markdown pour les adapter aux exigences de
# mkdocs
# On utilise donc pandoc pour convertir du markdown en markdown avec les options
# suivantes:
#
# - supprimer les commandes latex ( \newpage ) avec `-raw_tex-raw_attribute`
# - mkdocs met le titre en <H1>, il faut donc "décaler" tous les titres avec
#   l'option `--shift-heading-level-by=1`
# - mkdocs a besoin que les tables soient au format pipe_tables alors
#   on désactive les autres formats `-simple_tables-multiline_tables-grid_tables`
# - mkdocs et pandoc n'ont pas la meme syntaxe pour les admonitions, on utilise
#   un filtre lua de conversion
#
$(MKDOCS_PREPROCESS_DIR)/%.md: $(DALIDOC_BUILD_DIR)/%.markdown
	mkdir -p $(MKDOCS_PREPROCESS_DIR)
	$(PANDOC) \
	  --to markdown-raw_tex-raw_attribute-simple_tables-multiline_tables-grid_tables \
	  --shift-heading-level-by=1 \
	  --lua-filter=$(DALIDOC)/portal/convert_admonitions_for_mkdocs.lua \
	  $(PANDOC_ARGS) \
	  $^ --output $@

# Une fois le prétaitement effectué, lancer la génération du site
.PHONY: portal
portal: $(MD_FOR_MKDOCS) #: Générer le site du client
	mkdir -p $(MKDOCS_PREPROCESS_DIR)
	# Récupérer les fichiers du portail générique
	$(RSYNC) $(MKDOCS_BASE_DIR)/* $(MKDOCS_PREPROCESS_DIR)
	# Récupérer les fichiers du portail local
	$(RSYNC) --ignore-missing-args portal/* $(MKDOCS_PREPROCESS_DIR)
	# Recopier les medias et images (s'il yen a)
	# Le caractère '-' permet de continuer si le dossier medias n'existe pas
	-$(RSYNC) --ignore-missing-args $(DALIDOC_MEDIAS_DIR) $(MKDOCS_PREPROCESS_DIR)/
	# Recopier les artefacts
	$(RSYNC) --ignore-missing-args $(DOCS_ALL) $(MKDOCS_PREPROCESS_DIR)/
	# Générer le site
	$(MKDOCS) build --config-file $(MKDOCS_PREPROCESS_DIR)/mkdocs.yml

##
## Bridoulou
## Client factice pour tester en local et en CI
##

BRIDOULOU?=_bridoulou
TMPL=dalidoc/templates

.PHONY: _bridoulou

_bridoulou:
	mkdir -p $(BRIDOULOU)
	# Simuler le submodule dalidoc dans le dossier bridoulou
	$(RSYNC) --exclude $(BRIDOULOU) --exclude .git . $(BRIDOULOU)/dalidoc
	# Déployer un nouveau projet à partir du template
	$(RSYNC) $(BRIDOULOU)/$(TMPL)/project/ $(BRIDOULOU)
	# Déployer les templates de docs
	cp $(BRIDOULOU)/$(TMPL)/docs/_template_cra.md $(BRIDOULOU)/DLB-00000-000-CRA-0000.md
	cp $(BRIDOULOU)/$(TMPL)/docs/_template_cr_audit-tri.md $(BRIDOULOU)/DLB-00000-000-CRT-0000.md
	$(RSYNC) $(BRIDOULOU)/$(TMPL)/docs/medias $(BRIDOULOU)
	# Déployer les livrables additionnels
	$(RSYNC) $(BRIDOULOU)/dalidoc/test/bridoulou/portal $(BRIDOULOU)
	# Adapter de l'index Bridoulou pour les tests
	sed -i 's/<!-- .*//' $(BRIDOULOU)/portal/index.md
	sed -i 's/^-->//' $(BRIDOULOU)/portal/index.md

##
## Nettoyage
##

DOCS_ALL=$(DOCS_EPUB) $(DOCS_HTML) $(DOCS_MD) $(DOCS_ODT) $(DOCS_PDF) $(DOCS_SLIDES) $(DOCS_TEX)

clean:: #: Supprime tous les artefacts
	rm -fr $(DOCS_ALL)
	rm -fr $(BRIDOULOU)
	rm -fr $(MKDOCS_SITE_DIR)
	rm -fr $(VENV)
