default: all
	# $^ -> finished $@ at $(shell date)

# Use GNU utilities here if they exist (via e.g. `brew`)
ECHO := $(shell which gecho 2>/dev/null || which echo)
FIND := $(shell which gfind 2>/dev/null || which find)
LN   := $(shell which gln 2>/dev/null || which ln)
MKDIR:= $(shell which gmkdir 2>/dev/null || which mkdir)

NEWEST          := $(shell $(FIND) . -type f -printf '%T@ %p\n' \
			| grep -vE '(cache|output|.doit.db|state_data|#|/sentinel)' \
			| sort -n | tail -1 | cut -f2- -d' ')
LATEX_MAKEFILES := $(shell $(FIND) latex -name Makefile)
LATEX_FOLDERS   := $(dir $(LATEX_MAKEFILES))
LATEX_TEX       := $(shell $(FIND) $(LATEX_FOLDERS) -maxdepth 1 -name [^.]\*.tex)
LATEX_SVGS      := $(patsubst %.tex,%.svg,$(LATEX_TEX))
FILES_SVGS      := $(patsubst latex/%,files/%,$(LATEX_SVGS))

PYTHON_JOBS     := $(wildcard python/*/)

MONTH_FOLDERS   := $(wildcard posts/20??/[0-9][0-9])
DATE_FOLDERS    := $(wildcard posts/20??/[0-9][0-9]/[0-9][0-9])
DATE_UP_INDEX   := $(patsubst posts/%,files/posts/%/index.html,$(MONTH_FOLDERS) $(DATE_FOLDERS))

MD_FILES	:= $(shell $(FIND) pages posts -type f -name \*.md)
RST_FILES	:= $(shell $(FIND) pages posts -type f -name \*.rst)

MD_ASSET_FOLDERS	:= $(patsubst %.md,%/assets, $(MD_FILES))
RST_ASSET_FOLDERS	:= $(patsubst %.rst,%/assets, $(RST_FILES))

NEAR_ASSET_FOLDERS   := $(MD_ASSET_FOLDERS) $(RST_ASSET_FOLDERS)
FAR_ASSET_FOLDERS    := $(patsubst %/assets,files/%/assets,$(NEAR_ASSET_FOLDERS))

NEAR_CODE_FOLDERS   := $(shell $(FIND) pages posts -type d -name code)
FAR_CODE_FOLDERS    := $(patsubst %/code,listings/%/code,$(NEAR_CODE_FOLDERS))

LIST_IGNORED_FILES_Z := git ls-files --ignored --exclude-standard --others -z

newest:
	@echo ================================================================
	@echo ================ updated file: $(NEWEST)
	@echo ================================================================

deploy:
	until $(MAKE) all ; do sleep 1 ; done
	../is_clean.py | grep revision | grep clean
	git push
	$(MAKE) orphan-clean
	date | tee output/deploy
	until $(MAKE) -B output ; do sleep 1 ; done
	nikola deploy
	rm -fv output/deploy

all: latex files python listings output
	# $^ -> finished $@ at $(shell date)
orphan-clean:
	nikola orphans | xargs -r rm -v
	$(FIND) output -type d -empty -print -delete
clean: latex-clean files-clean listings-clean
	rm -rf cache
	$(FIND) output -mindepth 1 -maxdepth 1 | grep -v sentinel | xargs rm -rfv
	$(FIND) output -type d -empty -print -delete
	# $^ -> finished $@ at $(shell date)

serve: all
	cd output && ../../serve_utf8.py
	# $^ -> finished $@ at $(shell date)

templates/sentinel.html: $(NEWEST)
	../is_clean.py | tee $@

output: templates/sentinel.html
	$(MKDIR) -p $@
	[ -e $@/busy ] && { \
		echo "===== oops: $@/busy exists =====" && exit 1; \
	} || { date | tee $@/busy ; }
	$(MAKE) -B $^
	nikola build || { rm $@/busy ; exit 1; }
	$(FIND) $@ -type f | xargs -r chmod 0644
	$(FIND) $@ -type d | xargs -r chmod 0755
	../is_clean.py | tee files/sentinel $@/sentinel # for the server
	rm -fv $@/busy
	touch $@
	# $^ -> finished $@ at $(shell date)

continuous: all
	while true ; do \
		[ -e output/deploy ] || \
			$(MAKE) -q -s latex output || \
			$(MAKE) newest all; \
		$(ECHO) -n -e \\r $$(date +"%F %T.%N :") "" ; \
		sleep 1; \
	done
	# $^ -> finished $@ at $(shell date)

tmux: all
	$(MAKE) $^
	#### This command-line thing would work if `make tmux` never
	#### ran in the background.
	# tmux split-window $(MAKE) continuous
	# tmux split-window $(MAKE) serve
	#### But sometimes `make tmux` gets called from the
	#### background, so this Python script is smart about *which*
	#### tmux window to modify.
	MAKE="$(MAKE)" ./make-tmux.py
	# $^ -> finished $@ at $(shell date)

latex: $(LATEX_SVGS) $(FILES_SVGS)
	touch $@
	# $^ -> finished $@ at $(shell date)
files/%.svg : latex/%.svg
	$(LN) -rs $< $@
latex/%.svg : latex/%.tex
	$(MAKE) -C $(dir $@)
	# $^ -> finished $@ at $(shell date)
latex-clean:
	$(foreach folder, $(LATEX_FOLDERS), $(MAKE) -C $(folder) clean;)
	# $^ -> finished $@ at $(shell date)

.PHONY:: python $(PYTHON_JOBS)
python: $(PYTHON_JOBS)
	# $^ -> finished $@ at $(shell date)
$(PYTHON_JOBS):
	$(MAKE) -C $@
	# $^ -> finished $@ at $(shell date)

.PHONY:: this_month
this_month:
	$(RM) -vf $@
	$(LN) -vfs $(lastword $(MONTH_FOLDERS)) $@

files: this_month files/assets files/indices
	touch $@
	# $^ -> finished $@ at $(shell date)
files-clean:
	$(LIST_IGNORED_FILES_Z) files | xargs -0 -r rm -v
	$(FIND) files -type d -empty -print -delete

files/indices: $(DATE_UP_INDEX)
	@ls -l $^ > $@
	# finished $@ at $(shell date)
files/posts/%/index.html: posts/%
	@$(MKDIR) -p $(dir $@) && cp -v files/pages/index.html $(dir $@)

files/assets: $(FAR_ASSET_FOLDERS)
	@ls -lLd $^ > $@
	# finished $@ at $(shell date)
$(NEAR_ASSET_FOLDERS):
	@$(MKDIR) -pv $@
files/%/assets: %/assets
	@rm -fv $@
	@$(MKDIR) -pv $(dir $@)
	$(LN) -rs $^ $@

listings: listings/auto
	touch $@
	# $^ -> finished $@ at $(shell date)
listings/auto: $(FAR_CODE_FOLDERS)
	# finished $@ at $(shell date)
listings/%/code : %/code
	@rm -fv $@
	@$(MKDIR) -pv $(dir $(dir $@))
	$(LN) -rs $^ $(dir $(dir $@))
	@$(MKDIR) -pv listings/auto
	rm -fv listings/auto/$(notdir $*)
	$(LN) -rsv $@ listings/auto/$(notdir $*)
	# $^ -> finished $@ at $(shell date)
listings-clean:
	rm -rfv listings/auto
	$(LIST_IGNORED_FILES_Z) listings | xargs -0 -r rm -v
	$(FIND) listings -type d -empty -print -delete
