topdir := $(dir $(lastword $(MAKEFILE_LIST)))
include $(topdir)/config.mk
pkgconfdir    ?= $(sysconfdir)/libretools.d
pkgdocdir     ?= $(docdir)/libretools
pkglibexecdir ?= $(libexecdir)/libretools

# Misc variables for use in recipes ############################################

# Usage: <INPUT $(edit) >OUTPUT
# Expand m4_include macros to use librelib
# This is used when using sources grabbed from devtools
edit = sed \
	-e 's|^\#!\s*/bin/bash|\#!/usr/bin/env bash|' \
	-e 's|m4_include(lib/\(.*\))|. "$$(librelib \1)"|' \
	-e 's|@sysconfdir@|$(sysconfdir)|g' \
	-e 's|@bindir@|$(bindir)|g'

# Usage: $(call indent,FILENAME)
# Command to auto-indent a file.
indent = emacs --batch $1 \
	--eval '(setq make-backup-files nil)' \
	--eval '(setq sh-basic-offset 8)' \
	--eval '(indent-region (point-min) (point-max) nil)' \
	-f save-buffer &>/dev/null

# Usage <INPUT $(pofmt) >OUTPUT
# Normalize a .po(t) file
pofmt = msguniq -Fi

# Usage: as a variable
# relative path to `/` from $(bindir)
# used for symlinking libexec files
rootdir = $(shell sed -r 's|^/||;s|[^/]+|..|g'<<<$(bindir))

# Detect things aboud the director we're in ####################################

progs += $(filter-out $(no-progs),$(shell find . -maxdepth 1 -type f -executable -printf '%f\n'))
confs += $(filter-out $(no-conf) ,$(wildcard *.conf))
mans  += $(filter-out $(no-mans) ,$(patsubst %.ronn,%,$(wildcard *.ronn)))
docs  += $(filter-out $(no-docs) HACKING.md,$(wildcard *.md) $(wildcard *.ronn))
libexecs +=
libs  +=

copy_files +=
build_files += $(progs) $(confs) $(mans) $(libexecs) $(libs) $(patsubst %.in,%,$(copy_files))
install_files += $(addprefix $(DESTDIR)$(bindir)/,$(progs)) \
                 $(addprefix $(DESTDIR)$(pkgconfdir)/,$(confs)) \
                 $(addprefix $(DESTDIR)$(pkglibexecdir)/,$(libexecs) $(libs)) \
                 $(addprefix $(DESTDIR)$(docdir)/libretools/,$(docs)) \
                 $(addprefix $(DESTDIR)$(mandir)/man1/,$(filter %.1,$(mans))) \
                 $(addprefix $(DESTDIR)$(mandir)/man2/,$(filter %.2,$(mans))) \
                 $(addprefix $(DESTDIR)$(mandir)/man3/,$(filter %.3,$(mans))) \
                 $(addprefix $(DESTDIR)$(mandir)/man4/,$(filter %.4,$(mans))) \
                 $(addprefix $(DESTDIR)$(mandir)/man5/,$(filter %.5,$(mans))) \
                 $(addprefix $(DESTDIR)$(mandir)/man6/,$(filter %.6,$(mans))) \
                 $(addprefix $(DESTDIR)$(mandir)/man7/,$(filter %.7,$(mans))) \
                 $(addprefix $(DESTDIR)$(mandir)/man8/,$(filter %.8,$(mans)))
clean_files += $(patsubst %.in,%,$(copy_files)) $(copy_files) $(mans) $(wildcard *.pot *.ugly*)

pots  += $(filter-out $(no-pots) ,$(sort $(progs) $(libexecs) $(libs)))
pot_files += $(addsuffix .pot,$(pots))

# Set the default target #######################################################

all: PHONY build

# Copy (files from devtools) ###################################################

copy: PHONY $(copy_files)

%.in: $(devtoolsdir)/%.in
	cp $< $@
%.in: $(devtoolsdir)/lib/%
	cp $< $@

# Build ########################################################################

build: PHONY $(build_files)

%: %.ronn
	ronn --roff $(RONNFLAGS) < '$<' > '$@'
%.html: %.ronn
	ronn --html $(RONNFLAGS) < '$<' > '$@'


# If we have a .patch file, the flow is:
#     $(devtoolsdir)/%.in -> %.in + %.patch -> %.ugly -> %
_do_patch = $(filter $(patsubst %.patch,%,$(wildcard *.patch)),$(patsubst %.in,%,$(copy_files)))
%.ugly: %.in %.patch Makefile
	cp $*.in $@
	@echo 'PATCH $@ $*.patch'; patch $@ $*.patch
$(sort $(_do_patch)): %: %.ugly Makefile
	@echo 'EDIT < $< > $@'; $(edit) <'$<' >'$@'
	@echo 'INDENT $@'; $(call indent,$@)
	$(if $(filter-out %.sh,$@),chmod 755 "$@")
# Otherwise, the flow is just
#     $(devtoolsdir)/%.in -> %.in -> %
%: %.in
	@echo 'EDIT < $< > $@'; $(edit) <"$<" >"$@"
	$(if $(filter-out %.sh,$@),chmod 755 "$@")
# work-around for what I currently believe to be a regression in Make
%.sh: %.sh.in
	@echo 'EDIT < $< > $@'; $(edit) <"$<" >"$@"
	$(if $(filter-out %.sh,$@),chmod 755 "$@")

# Build ########################################################################

pot: everything.pot

everything.pot: $(pot_files)
	cat $^ | $(pofmt) > '$@'

%.pot: % $(topdir)/src/lib/librexgettext
	$(topdir)/src/lib/librexgettext $(LIBREXGETTEXT_FLAGS) $< > '$@'

# Install ######################################################################

install: PHONY $(install_files)

# We sort the explicit targets because sort also removes duplicates; in a few
# cases, a target could be listed twice, which is a warning.

# bindir: $(progs) vs $(libexecs)
$(sort $(addprefix $(DESTDIR)$(bindir)/,$(filter-out $(libexecs),$(progs)))): $(DESTDIR)$(bindir)/%: %
	install -Dm755 '$<' '$@'
$(sort $(addprefix $(DESTDIR)$(bindir)/,$(libexecs))): $(DESTDIR)$(bindir)/%: %
	install -d '$(@D)'
	ln -sf '$(rootdir)$(pkglibexecdir)/$(@F)' "$@"
# pkglibexecdir: $(libexecs) vs $(libs)
$(sort $(addprefix $(DESTDIR)$(pkglibexecdir)/,$(libexecs))): $(DESTDIR)$(pkglibexecdir)/%: %
	install -Dm755 '$<' '$@'
$(sort $(addprefix $(DESTDIR)$(pkglibexecdir)/,$(libs))): $(DESTDIR)$(pkglibexecdir)/%: %
	install -Dm644 '$<' '$@'
# everything else
$(DESTDIR)$(pkgconfdir)/%: %
	install -Dm644 '$<' '$@'
$(DESTDIR)$(pkgdocdir)/%: %
	install -Dm644 '$<' '$@'
$(DESTDIR)$(mandir)/man1/%.1: %.1
	install -Dm644 '$<' '$@'
$(DESTDIR)$(mandir)/man2/%.2: %.2
	install -Dm644 '$<' '$@'
$(DESTDIR)$(mandir)/man3/%.3: %.3
	install -Dm644 '$<' '$@'
$(DESTDIR)$(mandir)/man4/%.4: %.4
	install -Dm644 '$<' '$@'
$(DESTDIR)$(mandir)/man5/%.5: %.5
	install -Dm644 '$<' '$@'
$(DESTDIR)$(mandir)/man6/%.6: %.6
	install -Dm644 '$<' '$@'
$(DESTDIR)$(mandir)/man7/%.7: %.7
	install -Dm644 '$<' '$@'
$(DESTDIR)$(mandir)/man8/%.8: %.8
	install -Dm644 '$<' '$@'

# Clean ########################################################################

clean: PHONY clean-hook
	rm -f -- $(clean_files)

clean-hook: PHONY

# Boiler-plate #################################################################

FORCE: PHONY
PHONY:
.PHONY: FORCE PHONY

.DELETE_ON_ERROR: