#
# this Makefile uses pattern rules
# it is supposed to work with Solaris make and GNU make
# it will not work with BSD make
#
SHELL = /bin/sh
BIN = $(HOME)/bin

# $(CVS2U) makes 'cvs diff -u' results suitable for patch
#
CVS2U = $(BIN)/cvsdiff2udiff

# auxiliaries
#
CIVFOREVER = $(BIN)/civserver-forever
CIVKILL    = $(BIN)/civserver-kill
LYNX = lynx

# options to compile with
#
CFGOPTIONS = --disable-client --disable-nls --disable-cvs-deps

# where to put patched and unpatched source trees
#
SRC = $(HOME)/src

# where to put compiled installed results
#
DST = $(HOME)/compiled

# where to get the unpatched sources, $(CODEBASE).tar.bz2
#
WWW = ftp://ftp.freeciv.org/pub/freeciv

# where to put patches drawn from Jitterbug
#
PCH = $(HOME)/patches

# where is the Jitterbug repository
#
BUG = 'http://www.freeciv.org/cgi-bin/bugs'

# the port to start the game on
#
PORT = 5570

# where games are started
#
GAME = $(HOME)/.freeciv/games

# removing empty files
#
rmifempty = if cmp /dev/null 2>/dev/null; then echo $@ is empty 1>&2; rm $@; exit 1; fi

# ensuring the existence of a directory
#
havedir = test -d $@ || mkdir $@

# the version identifying name of the original, unpatched tarball
#
CODEBASE = latest/freeciv-cvs-May-16
#CODEBASE = 
#CODEBASE = `basename $(VARIANT)`

# the identifying name of the version, including the choice of patches
#
VARIANT = $(CODEBASE)/$(ID)

# the Jitterbug bug id, under which a number of patches may have been posted
# must be a number
#
ID =

# test for an interesting SysV make feature
foo/bar: $$(@F) $$(@D)
# and a GNU make feature
DEP := $(basename $(TARGET))
TARGET = bar/foo

%.blup: $(BAR)foo
	@echo making $@ from $?, FOO=$(FOO), BAR=$(BAR)

BAR := $(dir $(MAKECMDGOALS))
#BAR := $(dir $@)
FOO = $(basename $@)

foo bar:
	@echo $@ dus

# test for pattern rule support - which we don't use, so this is not needed
#
maketest:
	@if echo '%:; @echo $$@' | $(MAKE) -f - foo 2>/dev/null \
	  | grep '^foo$$' >/dev/null ; \
	then \
	  echo $(MAKE) knows pattern rules -  using it 1>&2; \
	else \
	  echo $(MAKE) does not know pattern rules - try GNU make 1>&2; \
	  exit 1; \
	fi

# the directory in which a patch is fetched and prepared
#
# $(ID) is its (Jitterbug) bug id
$(PCH)/$(ID): $(PCH)
$(PCH):
	$(havedir)

# the directory in which the source tree is created,
#   possibly patched and possibly compiled
#
$(SRC)/$(CODEBASE): $(SRC)
$(SRC):
	$(havedir)

# the directory into which the compiled end result is installed
#
$(DST)/$(VARIANT): $(DST)
$(DST):
	$(havedir)

# the unpatched source tree
#
$(SRC)/$(CODEBASE): $(LYNX)
	$(havedir)
	cd $@ && $(LYNX) -source $(WWW)/$(CODEBASE).tar.bz2 \
	  | bunzip2 -c | tar xvf -

# the HTTP response header for the HTML version with Jitterbug id $(ID)
#
$(PCH)/$(ID)/head: $(PCH)/$(ID)
	HEAD $(BUG)\?findid=$(ID) > $@
	$(rmifempty)

# the HTMLified Jitterbug message with the given ID
#
$(PCH)/$(ID)/html: $(PCH)/$(ID)/head
	test X"`head -1 $?`" = 'X200 OK' || { echo $@ cannot be fetched 1>&2; exit 1; }
	GET $(BUG)\?findid=$(ID) > $@
	$(rmifempty)

# the Jitterbug category, needed to fetch the message in mbox format
#
$(PCH)/$(ID)/category: $(PCH)/$(ID)/html
	awk -F'[<>/]' '/<p>Viewing <a href="#themesg">/ {print $$5}' $? >$@
	$(rmifempty)

# the Jitterbug message in Unix mailbox format
# BUG: we don't look at replies yet !!!
#
$(PCH)/$(ID)/msg: $(PCH)/$(ID)/category
	GET $(BUG)/`head -1 $?`?download=`head -1 $?`/$(ID).bin > $@
	$(rmifempty)

# the attachment(s) from the Jitterbug message
#
$(PCH)/$(ID)/attachments: $(PCH)/$(ID)/attachments/number
$(PCH)/$(ID)/attachments: $(PCH)/$(ID)/msg
	$(havedir)
	cd $@ && munpack -t -f $?
	ls $@ | wc -l > $@/number

# the patch(es) from the Jitterbug message
#
$(PCH)/$(ID)/patches: $(FREECIV)
$(PCH)/$(ID)/patches: $(PCH)/$(ID)/patches/number
$(PCH)/$(ID)/patches: $(PCH)/$(ID)/attachments
	$(havedir)
	cd $? && \
	{ ok=0; ls | \
	  while read f; \
	  do cat $$f | \
	    if cd $(FREECIV) && patch -C -t 2>&1 | grep '^Patching file'; \
	    then \
	      echo $$f seems to be a valid patch; \
	      ok=`expr $$ok + 1`; \
	      rm -f $@/$$ok; ln $?/$$f $@/$$ok.patch; \
            else \
	      echo $$f does not seem a valid patch; \
            fi; \
	  done ; \
	  echo $$ok > $@/number; \
	}

# the source tree $(VARIANT) with the patch(es) from Jitterbug bugid $(ID)
#
$(SRC)/$(VARIANT)/$(ID): $(CVS2U) $(PCH)/$(ID)/patches
$(SRC)/$(VARIANT)/$(ID): $(SRC)/$(VARIANT)
	$(havedir)
	cd $? && find . | cpio -pdl $@
	for f in `ls $(PCH)/$(ID)/patches/*.patch 2>/dev/null`; \
	  do \
	    echo applying patch $$f ...; \
	    [ ! -f $$f ] || $(CVS2U) $$f | patch -fp1 || \
	      { echo "patch $$f failed (already applied?)" 1>&2; true; }; \
	  done

# the compiled and installed $(VARIANT)
#
$(DST)/$(VARIANT): $(SRC)/$(VARIANT)
	cd $?/freeciv && ./autogen.sh $(CFGOPTIONS) --prefix=$@
	cd $?/freeciv && nice -19 make -j 2 install


# checking the sanity of variables
#

checkID:
	@perl -e "exit '$(ID)' !~ /^\d+$$/" \
	  || { echo "Invalid value '$(ID)' for variable ID, must be a number"; exit 1; }

checkWWW:
	@perl -e "exit '$(WWW)' !~ /^(ftp|http):/" \
	  || { echo "Invalid value '$(WWW)' for variable WWW, must be a URL"; exit 1; }

checkCODEBASE:
	@perl -e "exit '$(CODEBASE)' !~ /./" \
	  || { echo "Invalid value '$(CODEBASE)' for variable CODEBASE, must be a path relative to '$(WWW)/' minus filename extension"; exit 1; }

checkVARIANT:
	@perl -e ";exit !(substr('$(VARIANT)',0,length '$(CODEBASE)') eq '$(CODEBASE)' && substr('$(VARIANT)',length '$(CODEBASE)') !~ /[^\d\/]/)" \
	  || { echo "Invalid value '$(VARIANT)' for variable VARIANT, is not '$(CODEBASE)' plus 0 or more Jitterbug ids separated by /"; exit 1; }

checkvars: checkID checkWWW checkCODEBASE checkVARIANT

# 'front end' of symbolic target names
#

#fetch: checkvars $(SRC)/$(VARIANT)
fetch:
	@echo $(MAKE) $(MFLAGS) $(.MAKEFLAGS)
	@echo Freeciv source fetched and patched

install: checkvars $(DST)/$(VARIANT)
	@echo Freeciv installed

#--- the rest is not functional yet, and will be replaced ---#

$(RC): $(CIVSERVER)
	echo "# startup file for civserver-cvs" > $(RC)
	echo "#" >> $(RC)
	echo "# used by $(CIVFOREVER)" >> $(RC)
	echo "#" >> $(RC)
	echo "cmdlevel ctrl" >> $(RC)
	echo "# for all!" >> $(RC)
	echo >> $(RC)
	stat $(CIVSERVER) | grep ^Modify | \
	awk '{printf "metainfo CVS UNSTABLE (compiled  %s %s %s %s)\n",\
		$$2,$$3,$$4,$$5}'  >> $(RC)
	echo >> $(RC)
	echo "set techlevel 0" >> $(RC)
	echo "set saveturns 1" >> $(RC)
	echo "set gamelog 20" >> $(RC)
	echo "set scorelog 1" >> $(RC)
	echo "set aifill 2" >> $(RC)

kill: $(CIVKILL)
	$(CIVKILL) $(PORT) || exit 0  # failure is OK

#run:  $(CIVFOREVER) $(SRCDIR)/data
run: $(CIVFOREVER)
	env CIVSERVERRC=$(RC) FREECIV_PATH=$(SRCDIR)/data $(CIVFOREVER) $(PORT) > /dev/null 2>&1 &

$(SRCDIR)/data: $(CIVSERVER)
