all: local

# Configuration (override on the commandline)

LUA_VER := 5.1
LUA := /usr/bin/lua$(LUA_VER)
LUAC := /usr/bin/luac$(LUA_VER)
PREFIX ?= /usr/local
INST_ROOT := $(PREFIX)
SYSCONF_DIR ?= /etc

# Internal stuff
LUA_MOD_PATH := $(INST_ROOT)/share/lua/$(LUA_VER)
LUA_MOD_INST_PATH := $(DESTDIR)$(LUA_MOD_PATH)
BIN_PATH := $(INST_ROOT)/bin
BIN_INST_PATH := $(DESTDIR)$(BIN_PATH)
LIB_BIN_PATH := $(INST_ROOT)/lib/gitano/bin
LIB_BIN_INST_PATH := $(DESTDIR)$(LIB_BIN_PATH)
SHARE_PATH := $(INST_ROOT)/share/gitano
SHARE_INST_PATH := $(DESTDIR)$(SHARE_PATH)
SKEL_INST_PATH := $(SHARE_INST_PATH)/skel
LANG_INST_PATH := $(SHARE_INST_PATH)/lang
MAN_PATH := $(INST_ROOT)/share/man
MAN_INST_PATH := $(DESTDIR)$(MAN_PATH)
PLUGIN_PATH := $(SYSCONF_DIR)/gitano/plugins:$(INST_ROOT)/lib/gitano/plugins

LIB_BINS := gitano-auth gitano-post-receive-hook gitano-update-hook	\
	    gitano-update-ssh gitano-pre-receive-hook gitano-smart-http.cgi \
	    gitano-command.cgi

BINS := gitano-setup

TEST_BIN_NAMES := gitano-test-tool

TESTS := 01-basics 02-commands-as 02-commands-config 02-commands-copy		\
         02-commands-count-objects 02-commands-create 02-commands-destroy	\
         02-commands-fsck 02-commands-gc 02-commands-graveyard			\
         02-commands-git-upload-archive 02-commands-group 02-commands-help	\
         02-commands-keyring \
         02-commands-ls 02-commands-rename 02-commands-rsync	\
         02-commands-sshkey 02-commands-user 02-commands-whoami 03-cgit-support	\
         03-shallow-push


MODS := gitano 								\
									\
	gitano.util							\
	gitano.actions gitano.config gitano.lace gitano.log		\
	gitano.repository gitano.supple 		\
	gitano.command gitano.admincommand gitano.usercommand		\
	gitano.repocommand gitano.copycommand gitano.auth gitano.plugins\
	gitano.i18n

SKEL_FILES := gitano-admin/rules/selfchecks.lace			\
	      gitano-admin/rules/aschecks.lace 				\
	      gitano-admin/rules/siteadmin.lace				\
	      gitano-admin/rules/destroyrepo.lace			\
	      gitano-admin/rules/remoteconfigchecks.lace		\
	      gitano-admin/rules/core.lace				\
	      gitano-admin/rules/renamerepo.lace			\
	      gitano-admin/rules/defines.lace				\
	      gitano-admin/rules/project.lace				\
	      gitano-admin/rules/adminchecks.lace			\
	      gitano-admin/rules/createrepo.lace

LANG_FILES := json.lua en.lua

MAN1S := gitano-setup.1


PLUGINS := rsync.lua archive.lua git-annex.lua

MOD_DIRS := gitano
MOD_FILES := $(patsubst %,%.lua,$(subst .,/,$(MODS)))
SRC_MOD_FILES := $(patsubst %,lib/%,$(MOD_FILES))

LOCAL_BINS := $(patsubst %,bin/%,$(BINS) $(LIB_BINS))
LIB_BIN_SRCS := $(patsubst %,bin/%.in,$(LIB_BINS))

TEST_BINS := $(patsubst %,testing/%,$(TEST_BIN_NAMES))
TEST_BIN_SRCS := $(patsubst %,%.in,$(TEST_BINS))

YARN := yarn

TESTS := $(patsubst %,testing/%.yarn,$(TESTS))

GEN_BIN := utils/install-lua-bin
RUN_GEN_BIN := $(LUA) $(GEN_BIN) $(LUA)
define GEN_LOCAL_BIN

$(RUN_GEN_BIN) $(shell pwd) $(shell pwd)/bin $(shell pwd)/lib $(shell pwd)/plugins $1 $2
chmod 755 $2

endef

define GEN_INSTALL_BIN

$(RUN_GEN_BIN) $(SHARE_PATH) $(LIB_BIN_PATH) $(LUA_MOD_PATH) $(PLUGIN_PATH) $1 $2
chmod 755 $2

endef

define GEN_INSTALL_MAN

cp $1 $2
chmod 644 $2

endef

define GEN_INSTALL_MOD

install -m 644 $1 $2

endef

local: $(LOCAL_BINS)
	$(LUAC) -p $(LOCAL_BINS)

clean:
	@echo "CLEAN: local binaries"
	@$(RM) $(LOCAL_BINS)
	@echo "CLEAN: test binaries"
	@$(RM) $(TEST_BINS)

distclean: clean
	@find . -name "*~" -delete

bin/%: bin/%.in $(GEN_BIN)
	$(call GEN_LOCAL_BIN,$<,$@)

testing/%: testing/%.in $(GEN_BIN)
	$(call GEN_LOCAL_BIN,$<,$@)

install: install-bins install-lib-bins install-mods install-skel install-man install-plugins install-lang

install-man:
	mkdir -p $(MAN_INST_PATH)/man1
	$(foreach MAN,$(MAN1S),$(call GEN_INSTALL_MAN,doc/$(MAN),$(MAN_INST_PATH)/man1/$(MAN)))

install-bins: $(BIN_SRCS) $(GEN_BIN)
	mkdir -p $(BIN_INST_PATH)
	$(foreach BIN,$(BINS),$(call GEN_INSTALL_BIN,bin/$(BIN).in,$(BIN_INST_PATH)/$(BIN)))

install-lib-bins: $(LIB_BIN_SRCS) $(GEN_BIN)
	mkdir -p $(LIB_BIN_INST_PATH)
	$(foreach BIN,$(LIB_BINS),$(call GEN_INSTALL_BIN,bin/$(BIN).in,$(LIB_BIN_INST_PATH)/$(BIN)))

install-mods: $(SRC_MOD_FILES)
	mkdir -p $(patsubst %,$(LUA_MOD_INST_PATH)/%,$(MOD_DIRS))
	$(foreach MOD,$(MOD_FILES),$(call GEN_INSTALL_MOD,lib/$(MOD),$(LUA_MOD_INST_PATH)/$(MOD)))

install-skel:
	mkdir -p $(SKEL_INST_PATH)/gitano-admin/rules
	for SKELFILE in $(SKEL_FILES); do \
		install -m 644 skel/$$SKELFILE $(SKEL_INST_PATH)/$$SKELFILE; \
	done

install-lang:
	mkdir -p $(LANG_INST_PATH)
	for LANGFILE in $(LANG_FILES); do \
		install -m 644 lang/$$LANGFILE $(LANG_INST_PATH)/$$LANGFILE; \
	done

install-plugins:
	mkdir -p $(DESTDIR)$(INST_ROOT)/lib/gitano/plugins
	mkdir -p $(DESTDIR)$(SYSCONF_DIR)/gitano/plugins
	for PLUGIN in $(PLUGINS); do \
		install -m 644 plugins/$$PLUGIN $(DESTDIR)$(INST_ROOT)/lib/gitano/plugins; \
	done
	for LANGFILE in $(wildcard $(patsubst %.lua,plugins/%_*.lua,$(PLUGINS))); do \
		install -m 644 $$LANGFILE $(DESTDIR)$(INST_ROOT)/lib/gitano/plugins; \
	done

override YARN_ARGS := $(YARN_ARGS)
ifneq ($(LUA_PATH),)
override YARN_ARGS += --env LUA_PATH="$(LUA_PATH)"
endif
ifneq ($(LUA_CPATH),)
override YARN_ARGS += --env LUA_CPATH="$(LUA_CPATH)"
endif
ifneq ($(SCENARIO),)
override YARN_ARGS += --run "$(SCENARIO)"
endif

ifneq ($(YARN_SNAPSHOT),)
override YARN_ARGS += --snapshot
endif

TEST_PROTO ?= ssh

ifeq ($(filter $(TEST_PROTO),ssh http),)
$(error TEST_PROTO should be ssh or http)
endif

ifeq ($(HTTP_FIRST_TEST_PORT),)
HTTP_FIRST_TEST_PORT = 8080
endif

plugin-check:
	$(LUAC) -p $(patsubst %,plugins/%,$(PLUGINS))
	for PLUGIN in $(patsubst %,plugins/%,$(PLUGINS)); do \
		env LUA_PATH="$(shell pwd)/lib/?.lua;;" $(LUA) $$PLUGIN; \
	done

basictest: local plugin-check $(TEST_BINS)
	@echo "Running basic yarns in '$(TEST_PROTO)' mode"
	@echo "Set TEST_PROTO if you want to change that"
	@$(YARN)							 \
		--env GTT="$$(pwd)/testing/gitano-test-tool"		 \
		--env GTT_PROTO=$(TEST_PROTO) 				 \
		--env HTTP_FIRST_TEST_PORT=$(HTTP_FIRST_TEST_PORT)       \
		$(YARN_ARGS)                                             \
	        testing/library.yarn testing/01*.yarn

test: local plugin-check sshtests httptests

sshtests: $(TEST_BINS)
	@echo "Running full yarns in 'ssh' mode"
	@$(YARN)							 \
		--env GTT="$$(pwd)/testing/gitano-test-tool"		 \
		--env GTT_PROTO=ssh 					 \
		--env HTTP_FIRST_TEST_PORT=$(HTTP_FIRST_TEST_PORT)       \
		$(YARN_ARGS)                                             \
	        testing/library.yarn $(TESTS)

ifeq ($(SKIP_HTTP_TESTS),)
httptests: $(TEST_BINS)
	@echo "Running full yarns in 'http' mode"
	@$(YARN)							 \
		--env GTT="$$(pwd)/testing/gitano-test-tool"		 \
		--env GTT_PROTO=http 					 \
		--env HTTP_FIRST_TEST_PORT=$(HTTP_FIRST_TEST_PORT)       \
		$(YARN_ARGS)                                             \
	        testing/library.yarn $(TESTS)
else
httptests:
	@echo "WARNING: Running of yarns in 'http' mode disabled."
	@echo "WARNING: Cannot guarantee Gitano will work in HTTP mode."
endif

testing/%: testing/%.in $(GEN_BIN)
	$(call GEN_LOCAL_BIN,$<,$@)

check: test
