.POSIX:
DATE         = 1970-01-01
VERSION      = 0.1.0
NAME         = euandre.org
NAME_UC      = $(NAME)
LANGUAGES    = en
## Installation prefix.  Defaults to "/usr".
PREFIX       = /usr
BINDIR       = $(PREFIX)/bin
LIBDIR       = $(PREFIX)/lib
INCLUDEDIR   = $(PREFIX)/include
SRCDIR       = $(PREFIX)/src/$(NAME)
SHAREDIR     = $(PREFIX)/share
LOCALEDIR    = $(SHAREDIR)/locale
MANDIR       = $(SHAREDIR)/man
DOCDIR       = $(SHAREDIR)/doc/$(NAME)
HTMLDIR      = $(SHAREDIR)/html/$(NAME)
EXEC         = ./
## Where to store the installation.  Empty by default.
DESTDIR      =
LDLIBS       =
PUBURL       = public.asc



.SUFFIXES:
.SUFFIXES: .adoc .conf .snippets .indexentry .feedentry .sortdata .xml .txt
.SUFFIXES: .htmlbody .htmlheader .htmlfooter .htmllisting .html .links .caslinks
.SUFFIXES: .categorydata .gz

.adoc.conf:
	mkwb conf src/global.conf $< > $@

.adoc.htmlbody:
	mkwb htmlbody     $< > $@

.htmlbody.html:
	mkwb html         $< > $@

.conf.htmlheader:
	mkwb html -H      $< > $@

.conf.htmlfooter:
	mkwb html -F      $< > $@

.conf.htmllisting:
	mkwb indexbody    $< > $@

.adoc.snippets:
	mkwb snippets     $< > $@

.conf.indexentry:
	mkwb indexentry   $< > $@

.htmlbody.feedentry:
	mkwb feedentry    $< > $@

.conf.sortdata:
	mkwb sortdata     $< > $@

.conf.categorydata:
	mkwb categorydata $< > $@

.adoc.links:
	mkwb links        $< > $@

.links.caslinks:
	grep -Ev '^(link|image):' $< | xargs -I_ sh -c '\
		printf "%s\n" "_" | sha256sum | \
		printf "%s\t%s\n" "`cut -d" " -f1`" "_"' > $@



all:
include deps.mk


sources.adoc          = $(articles.adoc) $(listings.adoc) $(pages.adoc)
sources.htmlbody      = $(sources.adoc:.adoc=.htmlbody)
sources.html          = $(sources.adoc:.adoc=.html)
sources.snippets      = $(sources.adoc:.adoc=.snippets)
sources.snippets.gz   = $(sources.adoc:.adoc=.snippets.gz)
sources.conf          = $(sources.adoc:.adoc=.conf)
sources.links         = $(sources.adoc:.adoc=.links)
sources.caslinks      = $(sources.adoc:.adoc=.caslinks)
articles.indexentry   = $(articles.adoc:.adoc=.indexentry)
articles.feedentry    = $(articles.adoc:.adoc=.feedentry)
articles.sortdata     = $(articles.adoc:.adoc=.sortdata)
articles.categorydata = $(articles.adoc:.adoc=.categorydata)
listings.htmlheader   = $(listings.adoc:.adoc=.htmlheader)
listings.htmlfooter   = $(listings.adoc:.adoc=.htmlfooter)
listings.htmllisting  = $(listings.adoc:.adoc=.htmllisting)
listings.html         = $(listings.adoc:.adoc=.html)
categories.xml        = $(categories.txt:.txt=.xml)
categories.xml.gz     = $(categories.txt:.txt=.xml.gz)

sources = \
	$(sources.adoc)                          \
	$(sources.extras)                        \
	$(images.svg)                            \
	src/content/favicon.ico                  \
	src/content/style.css                    \
	src/content/$(PUBURL)                    \

dynamic-contents = \
	$(sources.html)                          \
	$(feeds.xml)                             \

static-contents = \
	$(sources.extras)                        \
	$(images.svg)                            \
	src/content/favicon.ico                  \
	src/content/style.css                    \
	src/content/$(PUBURL)                    \
	src/content/.well-known/security.txt     \

dynamic-contents.gz = $(dynamic-contents:=.gz)

static-contents.gz = \
	$(images.svg:=.gz)                       \
	src/content/favicon.ico.gz               \
	src/content/style.css.gz                 \
	src/content/$(PUBURL).gz                 \
	src/content/.well-known/security.txt.gz  \

contents.gz = \
	$(dynamic-contents.gz)                   \
	$(static-contents.gz)                    \

contents = \
	$(dynamic-contents)                      \
	$(static-contents)                       \
	src/content/security.txt                 \
	src/content/security.txt.gz              \

all-filelists = \
	$(sources.snippets)                      \
	$(sources.snippets.gz)                   \
	$(categories.xml)                        \
	$(categories.xml.gz)                     \

all-contents = \
	$(contents)                              \
	$(contents.gz)                           \


derived-assets = \
	$(dynamic-contents)                      \
	$(contents.gz)                           \
	$(sources.htmlbody)                      \
	$(sources.snippets)                      \
	$(sources.snippets.gz)                   \
	$(sources.links)                         \
	$(sources.caslinks)                      \
	$(sources.conf)                          \
	src/dyn.conf                             \
	src/base.conf                            \
	src/global.conf                          \
	$(listings.htmlheader)                   \
	$(listings.htmlfooter)                   \
	$(listings.htmllisting)                  \
	$(articles.indexentry)                   \
	$(articles.feedentry)                    \
	$(articles.sortdata)                     \
	$(articles.categorydata)                 \
	$(categories.txt)                        \
	$(categories.xml)                        \
	$(categories.xml.gz)                     \
	email.txt                                \
	baseurl.txt                              \
	fingerprint.txt                          \
	expiry.txt                               \
	src/content/security.txt                 \
	src/content/security.txt.gz              \
	src/content/.well-known/security.txt     \
	src/all-contents.txt                     \
	src/all-filelists.txt                    \
	src/install.txt                          \
	src/sort-expected.txt                    \
	src/sort-given.txt                       \
	src/sources.txt                          \
	install.txt                              \
	sources.txt                              \

side-assets = \
	src/collections/*/*/*/*/*.html.*.txt     \
	src/collections/*/*/*/*/*.html.*.txt.gz  \
	src/collections/*/index.html.*.txt       \
	src/collections/*/sortdata.txt           \
	src/collections/*/feed.*.xml             \
	src/collections/*/feed.*.xml.gz          \
	src/collections/*/*.sortdata             \
	src/pages/*/*.html.*.txt                 \
	src/content/.well-known/                 \



## Default target.  Builds all artifacts required for testing
## and installation.
all: $(derived-assets)
all: src/content/$(PUBURL) src/content/favicon.ico


$(derived-assets): Makefile deps.mk
$(sources.conf): src/global.conf src/headers.txt


src/dyn.conf: email.txt baseurl.txt fingerprint.txt
	printf "export url_pre='%s'\n"   "`cat baseurl.txt`"      > $@
	printf "export email='%s'\n"     "`cat email.txt`"       >> $@
	printf "export publickey='%s'\n" "`cat fingerprint.txt`" >> $@
	printf "export publickey_url='$(PUBURL)'\n"              >> $@
	printf 'export sourcecode_url="$$url_pre/git/$(NAME)"\n' >> $@

src/base.conf: src/dyn.conf src/static.conf
	cat src/dyn.conf src/static.conf > $@

src/global.conf: src/base.conf
	mkwb conf -G src/base.conf > $@

$(listings.html):
	cat $*.htmlheader $*.htmllisting $*.htmlbody $*.htmlfooter > $@

$(categories.txt):
	mkwb categories $(@D) > $@

$(categories.xml):
	for f in `cat $*.txt`; do \
		c="`printf '%s\n' "$$f" | cut -d. -f2`"; \
		mkwb feed src/global.conf "$$f" > $(@D)/feed."$$c".xml; \
		printf '%s\n' $(@D)/feed."$$c".xml; \
	done > $@

$(feeds.xml):
	mkwb feed src/global.conf $(@D)/sortdata.txt > $@

$(contents.gz):
	gzip -9fk $*
	touch     $@

$(sources.snippets.gz) $(categories.xml.gz):
	if [ -s $* ]; then gzip -9fk `cat $*`; fi
	sed 's/$$/.gz/' $* > $@

src/content/$(PUBURL).gz: src/content/$(PUBURL)
src/content/$(PUBURL):
	gpg --export --armour "`jq -r '.email' < meta.json`" > $@

src/content/favicon.ico.gz: src/content/favicon.ico
src/content/favicon.ico: src/content/img/favicon.svg
	convert src/content/img/favicon.svg $@

email.txt: meta.json
	jq -r '.email' < meta.json > $@

baseurl.txt: meta.json
	jq -r '.baseurl' < meta.json > $@

fingerprint.txt: src/content/$(PUBURL)
	gpg --always-trust --no-keyring --show-key --with-colons \
			src/content/$(PUBURL) | \
		awk -F: '/^pub:/ { print $$5 }' > $@

expiry.txt: src/content/$(PUBURL)
	gpg --always-trust --no-keyring --show-key --with-colons \
			src/content/$(PUBURL) | \
		awk -F: '/^pub:/ { print $$7 }' | \
		xargs -I% date -Is -d@% > $@

src/content/security.txt.gz: src/content/.well-known/security.txt.gz
src/content/security.txt:    src/content/.well-known/security.txt
src/content/security.txt src/content/security.txt.gz:
	ln -fs .well-known/$(@F) $@

src/content/.well-known/security.txt.gz: src/content/.well-known/security.txt
src/content/.well-known/security.txt: email.txt baseurl.txt expiry.txt
	mkdir -p $(@D)
	printf 'Contact: mailto:%s\n'        "`cat email.txt`"    > $@
	printf 'Expires: %s\n'               "`cat expiry.txt`"  >> $@
	printf 'Encryption: %s/$(PUBURL)\n'  "`cat baseurl.txt`" >> $@
	printf 'Preferred-Languages: en, pt, fr, eo, es\n'       >> $@

src/sources.txt:
	printf '%s\n' $(sources) > $@

src/all-contents.txt:
	printf '%s\n' $(all-contents) > $@

src/all-filelists.txt:
	printf '%s\n' $(all-filelists) > $@

src/install.txt: src/all-contents.txt src/all-filelists.txt $(all-filelists)
	cat src/all-contents.txt `cat src/all-filelists.txt` > $@

sources.txt: src/sources.txt
install.txt: src/install.txt
sources.txt install.txt:
	sed 's|^src/content/||' src/$(@F) > $@



src/sort-expected.txt:
	dirname $(articles.adoc) | env LANG=POSIX.UTF-8 sort | uniq -c | \
		awk '{ printf "%s\t%s\n", $$2, $$1 }' > $@

src/sort-given.txt: $(sources.conf) src/sort-expected.txt
	awk '{ \
		"grep \"^export sort=\" " $$1 "/*.conf | wc -l" | getline cnt; \
		printf "%s\t%s\n", $$1, cnt; \
	}' src/sort-expected.txt > $@

check-unit-sorting: src/sort-expected.txt src/sort-given.txt
	diff -U10 src/sort-expected.txt src/sort-given.txt


.SUFFIXES: .updatedat-check
sources.updatedat-check = $(sources.adoc:.adoc=.updatedat-check)
$(sources.updatedat-check):
	. ./$*.conf && if [ -n "$$updatedat_epoch" ] && \
		[ "$$updatedat_epoch" -le "$$date_epoch" ]; then exit 3; fi

check-unit-updatedat: $(sources.updatedat-check)


.SUFFIXES: .links-internal-check
sources.links-internal-check = $(sources.adoc:.adoc=.links-internal-check)
$(sources.links-internal-check): $(sources.html)
	grep -E '^(link|image):' $*.links | cut -d: -f2- | \
		xargs -I% test -e $(*D)/%

check-unit-links-internal: $(sources.links-internal-check)


check-unit-links-external:


check-unit-links: check-unit-links-internal check-unit-links-external

check-unit: check-unit-sorting check-unit-updatedat check-unit-links


integration-tests = \

.PRECIOUS: $(integration-tests)
$(integration-tests): ALWAYS
	sh $@

check-integration: $(integration-tests)


## Run all tests.  Each test suite is isolated, so that a parallel
## build can run tests at the same time.  The required artifacts
## are created if missing.
check: check-unit check-integration



## Remove *all* derived artifacts produced during the build.
## A dedicated test asserts that this is always true.
clean:
	rm -rf $(derived-assets) $(side-assets)


## Installs into $(DESTDIR)$(PREFIX).  Its dependency target
## ensures that all installable artifacts are crafted beforehand.
install: all
	rsync --mkpath -a --files-from=install.txt src/content/ \
		'$(DESTDIR)$(HTMLDIR)'
	rsync --mkpath -a --files-from=sources.txt src/content/ \
		'$(DESTDIR)$(SRCDIR)'

## Uninstalls from $(DESTDIR)$(PREFIX).  This is a perfect mirror
## of the "install" target, and removes *all* that was installed.
## A dedicated test asserts that this is always true.
uninstall:
	rm -rf \
		'$(DESTDIR)$(SRCDIR)'                 \
		'$(DESTDIR)$(HTMLDIR)'                \



PORT = 3333
## Run file server for local installed static files.
run:
	serve -n -p $(PORT) -d '$(DESTDIR)$(HTMLDIR)'


ALWAYS: