#
#  make.problem
#
#  Put this in the directory above the various problem directories.
#
#  Targets:
#    Kattis-based - requires kattistools to be installed
#      deploy:  builds Kattis zip package in parent directory
#      verify:  runs full Kattis verifyproblem
#      docs: generates PDF and HTML versions of problem statement
#      run: runs all programs in submissions/ on all tests
#      setup: creates the Kattis directory structure
#    Native:
#      compile: attempts to compile all programs in submissions/accepted/
#               compiled code is left in Work/
#      diffs: runs all programs in submissions/accepted/ on all tests and
#             checks (simple text diff) against expected answers.
#             A .diff file is left behind in Work/ for all non-empty
#             differences found.
#             Finally, lists all such diff files.
#
SRC=submissions/accepted
EXPECTED=ans
CS=$(wildcard $(SRC)/*.c)
CPPVersions=$(CS:$(SRC)/%.c=%)
CPPS=$(wildcard $(SRC)/*.cpp)
CPPVersions=$(CPPS:$(SRC)/%.cpp=%)
Javas=$(wildcard $(SRC)/*.java)
JavaVersions=$(Javas:$(SRC)/%.java=%)
PYTHONS=$(wildcard $(SRC)/*.py)
PythonVersions=$(PYTHONS:$(SRC)/%.py=%)
EXES=$(CPPVersions:%=Work/%.exe) $(CS:%.c=Work/%.exe)
CLASSES=$(JavaVersions:%=Work/%.class)
TestIn=$(wildcard data/sample/*.in) $(wildcard data/secret/*.in)
TestAns=$(TestIn:%.in=%.$(EXPECTED))
COutputs=$(foreach cppv,$(CVersions),$(addsuffix .$(cppv).c,$(Tests)))
CPPOutputs=$(foreach cppv,$(CPPVersions),$(addsuffix .$(cppv).cpp,$(Tests)))
JavaOutputs=$(foreach javav,$(JavaVersions),$(addsuffix .$(javav).java,$(Tests)))
CPPdiffs=$(CPPOutputs:%=%.diff)
Cdiffs=$(COutputs:%=%.diff)
Javadiffs=$(JavaOutputs:%=%.diff)
#
Diffs= $(CPPdiffs) $(Javadiffs) $(Cdiffs)
#
#
CFLAGS=-g -O2 -std=gnu99 -static
CPPFLAGS=-g -O2 -std=gnu++11 -static
#JAVAPROG=java
#JAVAPROG=taskset --cpu-list 0 java
JAVAPROG=java
JAVAFLAGS=-XX:+UseSerialGC -Xss64m -Xms2048m -Xmx2048m -verbose:gc
PYTHONPROG=pypy
#

## Kattis-based targets

verify:
	verifyproblem .

docs:
	problem2pdf .
	problem2html .

run:
	verifyproblem -psubmissions .



setup:
	-mkdir -p data/sample
	-mkdir -p data/secret
	-mkdir input_format_validators
	-mkdir output_validators
	-mkdir problem_statement
	-mkdir -p submissions/accepted
	-mkdir -p submissions/run_time_error
	-mkdir -p submissions/time_limit_exceeded
	-mkdir -p submissions/wrong_answer

deploy:
	cd ..; zip -9 -r $(PROBLEM).kpp $(PROBLEM)/problem.yaml $(PROBLEM)/data $(PROBLEM)/input_format_validators $(PROBLEM)/problem_statement $(PROBLEM)/submissions $(PROBLEM)/output_validators


# Non-Kattis targets

compile: $(EXES) $(CLASSES)

setup: $(TestIn)

%.in: %.in.txt
	tr -d '\r' < $*.in.txt > $@

Work/%.exe: $(SRC)/%.c
	-mkdir Work
	g++ $(CFLAGS) -o $@ $(SRC)/$*.c -lm

Work/%.exe: $(SRC)/%.cpp
	-mkdir Work
	g++ $(CPPFLAGS) -o $@ $(SRC)/$*.cpp

Work/%.class: $(SRC)/%.java
	-mkdir Work
	cp $(SRC)/$*.java Work
	cd Work; javac -g -cp java $*.java


diffs: compile $(TestAns)
	-mkdir Work
	-cp submissions/accepted/*.py Work
	cp $(TestIn) Work
	cp $(TestAns) Work
	cd Work; for testInput in *.in; do \
	  test=`basename $$testInput .in` ;\
	  echo test is $$test ;\
	  for cppv in $(CPPVersions); do \
	    echo ./$$cppv.exe from $$test.in into $$test.$$cppv.cpp.out; \
	    time -o $$test.$$cppv.time ./$$cppv.exe < $$test.in > $$test.$$cppv.cpp.out; \
	    if ! cmp -s $$test.$$cppv.cpp.out $$test.$(EXPECTED); then \
	       diff $$test.$$cppv.cpp.out $$test.$(EXPECTED) > $$test.$$cppv.cpp.diff; \
	    fi; \
	  done; \
	  for cv in $(CVersions); do \
	    echo  ./$$cv.exe from $$test.in into $$test.$$cppv.c.out; \
	    time -o $$test.$$cv.time ./$$cv.exe < $$test.in > $$test.$$cppv.c.out; \
	    if ! cmp -s $$test.$$cv.c.out $$test.$(EXPECTED); then \
	       diff $$test.$$cv.c.out $$test.$(EXPECTED) > $$test.$$cv.c.diff; \
	    fi; \
	  done; \
	  for jv in $(JavaVersions); do \
	    echo $(JAVAPROG) $(JAVAFLAGS) $$jv from $$test.in into $$test.$$jv.java.out; \
	    time -o $$test.$$jv.time $(JAVAPROG) $(JAVAFLAGS) $$jv < $$test.in > $$test.$$jv.java.out; \
	    if ! cmp -s $$test.$$jv.java.out $$test.$(EXPECTED); then \
	       diff $$test.$$jv.java.out $$test.$(EXPECTED) > $$test.$$jv.java.diff; \
	    fi; \
	  done; \
	  for pv in $(PythonVersions); do \
	    echo $(PYTHONPROG) $$pv.py from $$test.in into $$test.$$pv.py.out; \
	    time -o $$test.$$pv.time $(PYTHONPROG) $$pv.py < $$test.in > $$test.$$pv.py.out; \
	    if ! cmp -s $$test.$$pv.py.out $$test.$(EXPECTED); then \
	       diff $$test.$$pv.py.out $$test.$(EXPECTED) > $$test.$$pv.py.diff; \
	    fi; \
	  done; \
	done
	echo Failed tests:
	find . -name '*.diff'


SamplesIn=$(sort $(wildcard data/sample/*.in))
Samples=$(SamplesIn:%.in=%)


examples.tex: $(SamplesIn)
	echo "%% example data" > examples.tex ; \
	caseNum=0; \
	for sample in $(Samples); do \
		caseNum=`expr $$caseNum + 1`; \
	    echo '\\sampleData{'$(PROBLEM)'}{'$$caseNum'}{'$$sample'}' >> examples.tex; \
	done; \




clean:
	-/bin/rm -rf Work bin $(PROBLEM).pdf $(PROBLEM)_html

#%.${EXPECTED}: %.in $(EXES) $(CLASSES)
#	${Gold} < $*.in > $*.${EXPECTED}

