#--*- Makefile -*--

# Generate automatic evaluation reports for submitted students'
# assignments.

#------------------------------------------------------------------------------

MAKECONF_FILES = ${filter-out %~, ${wildcard makeconf*}}

ifneq ("${MAKECONF_FILES}","")
include ${MAKECONF_FILES}
endif

#------------------------------------------------------------------------------

# Final result files:

EVALUATION_FILE = evaluation.lst

GRADING_DIR = grading

GRADE_FILE    = ${GRADING_DIR}/grades.csv
FEEDBACK_FILE = ${GRADING_DIR}/comments.zip

CHECK_LANGUAGE ?= lt_LT.UTF-8

CHECK_SCRIPT ?= ./scripts/check-assignment

# Input files:

GRADING_WORKBOOK = ${GRADING_DIR}/templates/grading-workbook.csv

ASSIGNMENTS := $(shell find [A-ZĄČĘĖĮŠŲŪ]* \
	-mindepth 1 -maxdepth 1 \
	-name "*.tar"   -o \
	-name "*.tar.*" -o \
	-name "*.tgz"   -o \
	-name "*.tbz2"  -o \
	-name "*.txz"   -o \
	-name "*.zip"   -o \
	-name "*.7z" \
)

# Constructed file names:

ASSIGNMENT_XOURNAL_COMMENTS = $(wildcard */*.xoj)

COMMENT_SUFFIX ?= -SGcomments

COMMENTED_PDF_FILES = ${ASSIGNMENT_XOURNAL_COMMENTS:%.pdf.xoj=%${COMMENT_SUFFIX}.pdf}

AUTOCOMMENTS ?= $(sort \
	$(subst .zip,-comment.txt, \
	$(subst .tar,-comment.txt, \
	$(subst .tgz,-comment.txt, \
	$(subst .tbz2,-comment.txt, \
	$(subst .txz,-comment.txt, \
	$(subst .tar.gz,-comment.txt, \
	$(subst .tar.bz2,-comment.txt, \
	$(subst .tar.xz,-comment.txt, \
	$(subst .7z,-comment.txt, \
	${ASSIGNMENTS:%.tgz=%-comment.txt}))))))))))

XOURNAL_COMMENTS = $(sort \
	$(patsubst %,%xournal-comments.txt,$(dir ${ASSIGNMENT_XOURNAL_COMMENTS})) \
)

TEACHER_COMMENTS = $(wildcard */teacher-comments.txt)
EXTRA_COMMENTS = $(wildcard */extra-comments.txt)

COMMENTS = $(sort \
	$(patsubst %,%comments.txt,$(dir ${AUTOCOMMENTS})) \
	$(patsubst %,%comments.txt,$(dir ${XOURNAL_COMMENTS})) \
	$(patsubst %,%comments.txt,$(dir ${TEACHER_COMMENTS})) \
)

MISSPELLED = ${COMMENTS:%.txt=%-spell.lst}

.PHONY: all pdf clean cleanAll distclean display spell aspell

.PHONY: autocomment autoteacher comment evaluate final grade feedback

.PHONY: wordlist words

all: comment autocomment pdf spell evaluate grade feedback

#------------------------------------------------------------------------------

MAKELOCAL_FILES = ${filter-out %~, ${wildcard makelocal*}}

ifneq ("${MAKELOCAL_FILES}","")
include ${MAKELOCAL_FILES}
endif

#------------------------------------------------------------------------------

# Allow to shorten 'make display VARIABLE=X' to 'make display VAR=X':
VAR      ?= PATH
VARIABLE ?= ${VAR}

display:
	@echo ${VARIABLE}=${${VARIABLE}}

#------------------------------------------------------------------------------

# Create students' directories:

# The students' list 'studentai.lst' should have the following format:

# - each person is listed on a separate line in the format "<Name>
# - <Surname>" or "<Surname> <Name>" (space separated, without
# - quotes). Each line should have identical format (i.e. no header).

STUDENT_LIST ?= ../../studentų-sąrašas/studentai.lst

.PHONY: students copies

students:
	cat ${STUDENT_LIST} \
	| awk -F"\t" '{print $$1}' \
	| sed 's/ /_/g' \
	| xargs mkdir -p -v

ATTEMPT_DIR ?= $(lastword $(sort $(wildcard unpacked/[0-9]*) unpacked))

copies: students backups
	./scripts/map-students-directories ${ATTEMPT_DIR} . \
	| awk -F "\t" \
		'{print "if [ -d ", "\""$$2"\"", "]; then svn cp --parents", "\""$$2"\"/*.*", $$1"/", "; fi"}' \
	| sh -x
	find [A-ZĄČĘĖĮŠŲŪ]* -name '* *' | xargs -i sh -c 'NEW="$$(echo "{}" | tr " " "_")"; svn mv "{}" "$${NEW}"'

.PHONY: backups

# TO-DO: move the loop below into a separate shell script; process
# './scripts/map-students-directories' outputs in a pipe (S.G. 2020-06-09):
backups:
	set -x; \
	for i in [A-ZĄČĘĖĮŠŲŪ]*; do ( \
		DIR=$$(./scripts/map-students-directories ${ATTEMPT_DIR} . | grep $$i \
			| awk -F'\t' '{print $$1}'); \
		if [ -n "$$DIR" -a $$(find "$$DIR" -mindepth 1 | wc -l) -gt 0 ]; then \
			PREV_DIR="$$i/previous-attempt"; \
			if [ -d "$${PREV_DIR}" ]; then \
				echo "$${PREV_DIR} already exists -- skipping backup"; \
				continue; \
			fi; \
			svn mkdir --parents $${PREV_DIR}; \
			for j in $$(ls -1d $$i/* | grep -v '^.*-attempt' ); do \
				svn mv "$$j" $${PREV_DIR}; \
			done; \
			for j in $$(ls -1d $$i/* | grep -v '^.*-attempt' ); do \
				mv -v "$$j" $${PREV_DIR}; \
			done; \
		else \
			echo "Update for '$$i' is not present or no previous attempt," \
				" leaving it as it is"; \
		fi \
	) done
	for i in [A-ZĄČĘĖĮŠŲŪ]*/previous-attempt; do \
		if [ -d "$$i" ]; then \
			svn ps 'svn:ignore' "$$(echo unpacked; echo tmp)" $$i; \
		fi; \
	done

#------------------------------------------------------------------------------

XOURNAL_DEPEND=.xournal-comments.d

include ${XOURNAL_DEPEND}

${XOURNAL_DEPEND}: ${ASSIGNMENT_XOURNAL_COMMENTS}
	echo "# $$(date +'%F %T')" > $@
	for i in $(sort $(patsubst %,%xournal-comments.txt,$(dir $^))); do \
		echo "$$i:" "$$(dirname "$$i")/"*.xoj >> $@; \
		echo "$$(dirname "$$i")/comments.txt: $$i"  >> $@; \
	done

autocomment: ${AUTOCOMMENTS}

autoteacher: ${AUTOCOMMENTS}
	for i in */*-comment.txt; do ( \
		set -x; \
		DIR=$$(dirname $$i); \
		TC=$$DIR/teacher-comments.txt; \
		test -f $$TC || ls -1t $$DIR/*-comment.txt | head -1 | xargs -i cp -v {} $$TC; \
		test -f $$TC && touch $$TC; \
	) done

comment: ${COMMENTS}

.PHONY: commented-pdf pdf

commented-pdf pdf: ${COMMENTED_PDF_FILES}

%${COMMENT_SUFFIX}.pdf: %.pdf.xoj
	@echo "Please use 'xournal' interactively to export the '$@' file"
	@xournal $<

.PHONY: unpack ignore

ignore:
#	scripts/set-svn-ignore *
	for i in $(sort $(dir ${COMMENTS})); do \
		svn pd svn:ignore $$i; \
		svn ps svn:ignore "$$(echo unpacked; echo tmp)" $$i; \
		svn pg svn:ignore $$i | grep . > $$i.gitignore; \
	done

unpack:
	for i in [A-ZĄČĘĖĮŠŲŪ]*/*.*; do ( \
		cd $$(dirname $$i); \
		case $$i in \
			*.tgz|*.tbz2|*.tar|*.txz|*.tar.*) \
				rm -rf unpacked; \
				mkdir -p unpacked; \
				echo "Archive:" $$i; \
				tar -C unpacked -vxf $$(basename $$i) ;; \
			*.zip) \
				rm -rf unpacked; \
				mkdir -p unpacked; \
				ARCHIVE=$$(pwd)/$$(basename $$i); \
				cd unpacked; \
				unzip -o $${ARCHIVE} ;; \
			*.7z) \
				rm -rf unpacked; \
				mkdir -p unpacked; \
				ARCHIVE=$$(pwd)/$$(basename $$i); \
				echo "Archive:" $${ARCHIVE}; \
				cd unpacked; \
				7z -aoa x $${ARCHIVE} > /dev/null ;; \
		esac; \
	) done

EVALUATION ?= "preliminarus"
MAX_POINTS ?= 100

evaluate: ${EVALUATION_FILE}
	cat $<

${EVALUATION_FILE}: ${COMMENTS}
	date +'# %F %T %Z' > $@
	@for i in */comments.txt; do ( \
		POINTS=$$(expr ${MAX_POINTS} + $$(scripts/evaluate-assignment "$$i")) ;\
		echo -n $${POINTS}/${MAX_POINTS}"\t" ;\
		echo -n "$$(dirname "$$i" | sed 's/_/ /g')" "-- " ;\
		if [ $$POINTS -ge ${MAX_POINTS} ]; then \
			echo -n "galutinis įvertinimas. " ;\
		else \
			echo -n "${EVALUATION} įvertinimas. " ;\
		fi; \
		echo -n " Komentarai faile '$$(basename "$$i")'" ;\
		echo "" ;\
	) done \
	>> $@

final:
	${MAKE} EVALUATION="galutinis" evaluate

grade: ${GRADE_FILE}

feedback: ${FEEDBACK_FILE}

WORDS ?= "./žodžiai.lst"

words wordlist: ${WORDS}

${WORDS}: ${EXTRA_COMMENTS} ${TEACHER_COMMENTS} ${XOURNAL_COMMENTS}
	for file in $^; do \
		aspell -l ${CHECK_LANGUAGE} list < $$file \
		| iconv -t ISO-8859-13 \
		| aspell -l lt clean; \
	done \
	| sort -u \
	| tac \
	| awk '{n++; print} END {printf "personal_ws-1.1 lt %d \n", n}' \
	| tac > $@

aspell: ${TEACHER_COMMENTS} ${XOURNAL_COMMENTS} ${EXTRA_COMMENTS}
	for file in $^; do \
		aspell -x -p ${WORDS} -l ${CHECK_LANGUAGE} -c $$file; \
	done

spell: ${MISSPELLED}
	@test -z "$<" || head -n 20 $^

#------------------------------------------------------------------------------

GET_LANGUAGE = $$(awk -F. '{print $$1}' $(word 3,$^))

%/comments-spell.lst: %/extra-comments.txt %/teacher-comments žodžiai.lst %/language.dat
	tail -n +2 $(word 1,$^) $(word 2,$^) \
	| aspell -p ./${GET_LANGUAGE}.lst -l ${GET_LANGUAGE} list \
	| sort -u | tee $@

%/comments-spell.lst: %/extra-comments.txt žodžiai.lst %/language.dat
	tail -n +2 $< \
	| aspell -p ./${GET_LANGUAGE}.lst -l ${GET_LANGUAGE} list \
	| sort -u | tee $@

%/comments-spell.lst: %/teacher-comments.txt žodžiai.lst %/language.dat
	tail -n +2 $< \
	| aspell -p ./${GET_LANGUAGE}.lst -l ${GET_LANGUAGE} list \
	| sort -u | tee $@

#------------------------------------------------------------------------------

%/comments-spell.lst: %/extra-comments.txt %/teacher-comments žodžiai.lst
	tail -n +2 $(word 1,$^) $(word 2,$^) \
	| aspell -p ${WORDS} -l ${CHECK_LANGUAGE} list \
	| sort -u | tee $@

%/comments-spell.lst: %/extra-comments.txt žodžiai.lst
	tail -n +2 $< \
	| aspell -p ${WORDS} -l ${CHECK_LANGUAGE} list \
	| sort -u | tee $@

%/comments-spell.lst: %/teacher-comments.txt žodžiai.lst
	tail -n +2 $< \
	| aspell -p ${WORDS} -l ${CHECK_LANGUAGE} list \
	| sort -u | tee $@

%/comments-spell.lst:
	touch $@

#------------------------------------------------------------------------------

%/comments.txt: %/extra-comments.txt %/teacher-comments.txt
	echo $@ $$(date +"%F %T") "(from files $^)" > $@
	echo "" >> $@
	head -n1 $(lastword $^) >> $@
	echo "" >> $@
	cat $(firstword $^) >> $@
	tail -n +2 $(lastword $^) >> $@

%/comments.txt: %/extra-comments.txt %/autocomment.txt
	echo $@ $$(date +"%F %T") "(from files $^)" > $@
	echo "" >> $@
	head -n1 $(lastword $^) >> $@
	echo "" >> $@
	cat $(firstword $^) >> $@
	tail -n +2 $(lastword $^) >> $@

%/comments.txt: %/teacher-comments.txt
	echo $@ $$(date +"%F %T") "(from files $^)" > $@
	echo "" >> $@
	cat $$(ls -r1 $^) >> $@

%/comments.txt: %/autocomment.txt
	echo $@ $$(date +"%F %T") "(from files $^)" > $@
	echo "" >> $@
	cat $$(ls -r1 $^) >> $@

%/xournal-comments.txt:
	echo $@ $$(date +"%F %T") "(from files $^)" > $@
	echo "" >> $@
	./scripts/extract-xournal-comments $(filter $(dir $@)%,$^) >> $@

#------------------------------------------------------------------------------

# Generate autocomment files for transferring them into comments, in
# case teacher comments are not present:

AUTOCOMMENT_DEPEND = .autocomment.d

include ${AUTOCOMMENT_DEPEND}

${AUTOCOMMENT_DEPEND}: ${ASSIGNMENTS}
	date "+# %F %T %Z" > $@
	echo ${AUTOCOMMENTS} \
	| tr " " "\n" \
	| grep . \
	| xargs -i sh -c 'echo $$(dirname {}) {}' \
	| awk '{print $$1"/autocomment.txt: ", $$2}' \
	>> $@

%/autocomment.txt:
	ls -1t $^ | head -n 1 | xargs -i cp -v {} $@

#------------------------------------------------------------------------------

# Create files with language specifications of they are given for a
# specific assignment:

LANGUAGE_WILDCARDS ?= $(sort \
	$(subst .zip,-language*.dat, \
	$(subst .tar,-language*.dat, \
	$(subst .tgz,-language*.dat, \
	$(subst .tbz2,-language*.dat, \
	$(subst .txz,-language*.dat, \
	$(subst .tar.gz,-language*.dat, \
	$(subst .tar.bz2,-language*.dat, \
	$(subst .tar.xz,-language*.dat, \
	$(subst .7z,-language*.dat, \
	${ASSIGNMENTS:%.tgz=%-language*.dat}))))))))))

LANGUAGE_SPEC_FILES ?= $(wildcard ${LANGUAGE_WILDCARDS})

LANGUAGE_DEPEND ?= .language.d

include ${LANGUAGE_DEPEND}

${LANGUAGE_DEPEND}: ${ASSIGNMENTS}
	date "+# %F %T %Z" > $@
	echo ${LANGUAGE_SPEC_FILES} \
	| tr " " "\n" \
	| grep . \
	| xargs -i sh -c 'echo $$(dirname {}) {}' \
	| awk '{print $$1"/language.dat: ", $$2}' \
	>> $@

%/language.dat:
	ls -1t $^ | head -n 1 | xargs -i cp -v {} $@

#------------------------------------------------------------------------------

CHECK_SCRIPT_WITH_LANGUAGE = ${CHECK_SCRIPT} --language $$(cat $(word 2,$^))

%-comment.txt: %.tgz %-language.dat
	${CHECK_SCRIPT_WITH_LANGUAGE} $< > $@

%-comment.txt: %.txz %-language.dat
	${CHECK_SCRIPT_WITH_LANGUAGE} $< > $@

%-comment.txt: %.tbz2 %-language.dat
	${CHECK_SCRIPT_WITH_LANGUAGE} $< > $@

%-comment.txt: %.tar %-language.dat
	${CHECK_SCRIPT_WITH_LANGUAGE} $< > $@

%-comment.txt: %.tar.gz %-language.dat
	${CHECK_SCRIPT_WITH_LANGUAGE} $< > $@

%-comment.txt: %.tar.bz2 %-language.dat
	${CHECK_SCRIPT_WITH_LANGUAGE} $< > $@

%-comment.txt: %.tar.xz %-language.dat
	${CHECK_SCRIPT_WITH_LANGUAGE} $< > $@

%-comment.txt: %.zip %-language.dat
	${CHECK_SCRIPT_WITH_LANGUAGE} $< > $@

%-comment.txt: %.7z %-language.dat
	${CHECK_SCRIPT_WITH_LANGUAGE} $< > $@

#------------------------------------------------------------------------------

%-comment.txt: %.tgz
	${CHECK_SCRIPT} --language ${CHECK_LANGUAGE} $< > $@

%-comment.txt: %.txz
	${CHECK_SCRIPT} --language ${CHECK_LANGUAGE} $< > $@

%-comment.txt: %.tbz2
	${CHECK_SCRIPT} --language ${CHECK_LANGUAGE} $< > $@

%-comment.txt: %.tar
	${CHECK_SCRIPT} --language ${CHECK_LANGUAGE} $< > $@

%-comment.txt: %.tar.gz
	${CHECK_SCRIPT} --language ${CHECK_LANGUAGE} $< > $@

%-comment.txt: %.tar.bz2
	${CHECK_SCRIPT} --language ${CHECK_LANGUAGE} $< > $@

%-comment.txt: %.tar.xz
	${CHECK_SCRIPT} --language ${CHECK_LANGUAGE} $< > $@

%-comment.txt: %.zip
	${CHECK_SCRIPT} --language ${CHECK_LANGUAGE} $< > $@

%-comment.txt: %.7z
	${CHECK_SCRIPT} --language ${CHECK_LANGUAGE} $< > $@

#------------------------------------------------------------------------------

${GRADE_FILE}: ${EVALUATION_FILE} ${GRADING_WORKBOOK}
	./scripts/merge-moodle-grading-worksheet $^ > $@

${GRADING_DIR}/%.zip: ${COMMENTS}
	DIR=tmp-$$$$-feedback; \
	mkdir $${DIR}; \
	tail -n +2 ${GRADING_WORKBOOK} \
	| awk -F, '/Dalyvis|Participant/{print $$2 "\t" $$1}' \
	| sed 's/"//g; s/\(Dalyvis\|Participant\) *//' \
	| awk -F"\t" -v DIR=$${DIR} '{ \
		print "mkdir -p", "\"" DIR "/" $$1 "_" $$2 "_assignsubmission_file_\""; \
		src = $$1; \
		gsub( " ", "_", src ); \
		print "test -f " src "/comments.txt && cp", src "/comments.txt", \
                      "\"" DIR "/" $$1 "_" $$2 "_assignsubmission_file_\";"; \
		print "test -f " src "/*comments.pdf && cp", src "/*comments.pdf", \
                      "\"" DIR "/" $$1 "_" $$2 "_assignsubmission_file_\"" \
	}' | sh -x; \
	rmdir --ignore-fail-on-non-empty $${DIR}/*; \
	( cd $${DIR}; zip -r ../$@ */* ); \
	rm -rf $${DIR}

.PHONY: pdfclean

pdfclean:
	rm -f ${COMMENTED_PDF_FILES}

clean:
	rm -f ${COMMENTS}
	rm -f ${XOURNAL_COMMENTS}
	rm -f ${MISSPELLED}

distclean cleanAll: clean pdfclean
	rm -f ${AUTOCOMMENTS}
	rm -f ${EVALUATION_FILE}
	rm -f ${GRADE_FILE}
	rm -f ${FEEDBACK_FILE}
	rm -f ${AUTOCOMMENT_DEPEND}
	rm -f ${XOURNAL_DEPEND}
