PREFIX ?= /usr/local

ifeq ($(PREFIX),/usr)
	ETCDIR ?= /etc
else
	ETCDIR ?= $(PREFIX)/etc
endif

BINDIR ?= $(PREFIX)/bin

OCAMLFIND ?= ocamlfind
OCAMLDEP ?= ocamldep

OCAMLBEST ?= $(shell if $(OCAMLFIND) ocamlopt > /dev/null 2>&1; then echo opt; else echo byte; fi)
OCAMLMAJORVERSION := $(shell $(OCAMLFIND) ocamlc -version 2>/dev/null | cut -d '.' -f 1)
INSTALL ?= install

OCAML_PKGS := unix str curses yojson

# Assuming any version neq 4 is gt 4
ifneq ($(OCAMLMAJORVERSION),4)
	OCAML_PKGS += camlp-streams
endif


all: wyrd doc

doc:
	$(MAKE) -C doc

clean: distclean
	$(MAKE) -C doc clean

distclean: clean
	rm -f *.cm[iox] *.o wyrd install.ml depend test.rem expect.log
	$(MAKE) -C doc distclean


# bytecode and native-code compilation

ML_SOURCE := $(shell $(OCAMLFIND) ocamldep -sort $(wildcard *.ml))

CMO = $(ML_SOURCE:.ml=.cmo)
CMX = $(ML_SOURCE:.ml=.cmx)

COBJS = locale_wrap.o

OCAMLFIND_PKG_FLAGS = $(patsubst %,-package %,$(OCAML_PKGS))

ifeq ($(OCAMLBEST),opt)
wyrd: $(COBJS) $(CMX)
	$(OCAMLFIND) ocamlopt -linkpkg $(OCAMLFLAGS) $(OCAMLFIND_PKG_FLAGS) -o $@ $(CMX) $(COBJS)
else
wyrd: $(COBJS) $(CMO)
	$(OCAMLFIND) ocamlc -custom -linkpkg $(OCAMLFLAGS) $(OCAMLFIND_PKG_FLAGS) -o $@ $(CMO) $(COBJS)
endif

dist: VERSION=$(shell test $$WYRD_VERSION && echo $$WYRD_VERSION || git describe --tags)
dist: distclean
	mkdir wyrd-$(VERSION)
	cp -r doc locale_wrap.c COPYING ChangeLog Makefile README.md dune wyrdrc *.ml *.mli wyrd-$(VERSION)/
	sed "s/@PACKAGE_VERSION@/$(VERSION)/" install.ml.in > wyrd-$(VERSION)/install.ml.in
	sed "s/@WYRD_VERSION@/$(VERSION)/" _oasis.in > wyrd-$(VERSION)/_oasis
	sed "/(name wyrd)/a (version $(VERSION))" dune-project > wyrd-$(VERSION)/dune-project
	cd wyrd-$(VERSION); dune build --release ./wyrd.opam
	rm -rf wyrd-$(VERSION)/_build
	make -C wyrd-$(VERSION)/doc manual
	make -C wyrd-$(VERSION)/doc distclean
	tar -cJf wyrd-$(VERSION).tar.xz wyrd-$(VERSION)
	rm -rf wyrd-$(VERSION)

install: wyrd
	$(INSTALL) -d $(DESTDIR)$(BINDIR)
	$(INSTALL) -m 755 wyrd $(DESTDIR)$(BINDIR)/wyrd
	$(MAKE) -C doc install DESTDIR=$(abspath $(DESTDIR))

uninstall:
	rm -f $(DESTDIR)$(BINDIR)/wyrd
	$(MAKE) -C doc uninstall DESTDIR=$(abspath $(DESTDIR))

test:
	./wyrd --add "drop off package at 3pm" test.rem
	TERM=linux expect -c 'log_file expect.log; \
	     set stty_init "rows 60 columns 80"; \
	     spawn -nottycopy ./wyrd test.rem; \
	     expect_before timeout { exit 1 }; \
	     expect -re "15:00.*drop off package" { send Q; expect eof } eof; \
	     exit [lindex [wait] 3]'
	rm test.rem
	-reset

.SUFFIXES:

# generic build rules for toplevel directory
%.cmi : %.mli
ifeq ($(OCAMLBEST),opt)
	$(OCAMLFIND) ocamlopt -c -o $@ $(OCAMLFIND_PKG_FLAGS) $(OCAMLFLAGS) $<
else
	$(OCAMLFIND) ocamlc -c -o $@ $(OCAMLFIND_PKG_FLAGS) $(OCAMLFLAGS) $<
endif

%.cmo : %.ml %.cmi
	$(OCAMLFIND) ocamlc -c -o $@ $(OCAMLFIND_PKG_FLAGS) $(OCAMLFLAGS) $<

%.o : %.ml
	$(OCAMLFIND) ocamlopt -c -o $@ $(OCAMLFIND_PKG_FLAGS) $(OCAMLFLAGS) $<

%.cmx : %.ml %.cmi
	$(OCAMLFIND) ocamlopt -c -o $@ $(OCAMLFIND_PKG_FLAGS) $(OCAMLFLAGS) $<

%.o : %.c
	$(OCAMLFIND) ocamlc -c -o $@ $(OCAMLFIND_PKG_FLAGS) $(CFLAGS:%=-ccopt %) $(OCAMLFLAGS) $<

install.ml: install.ml.in
	sed -e "s|@prefix@|$(PREFIX)|" \
	    -e "s|@sysconfdir@|$(ETCDIR)|" \
	    -e "s|@PACKAGE_VERSION@|$(shell test $$WYRD_VERSION && echo $$WYRD_VERSION || git describe --tags)|" $< > $@


# calculate inter-file dependencies for parallel make
depend: install.ml
	$(OCAMLDEP) *.ml *.mli > $@

include depend

.PHONY: all clean dist distclean doc install uninstall test
