# this can do multipage
#go5:
#	dot -Tps server.dot > server.ps
#	evince server.ps

#backshift_filesystem.py
#fses.py
#hardlinks.py
#test_backshift_filesystem.py
modules=varblock_mod.py

pylint_files= \
	backshift/backshift_file_mod.py  \
	backshift/base255.py \
	backshift/bloom_filter_mod.py  \
	backshift/bufsock.py  \
	backshift/cacher_mod.py \
	backshift/chunk_mod.py \
	backshift/compressed_file_mod.py \
	backshift/constants_mod.py \
	backshift/dirops_mod.py \
	backshift/dohdbm.py \
	backshift/escape_mod.py \
	backshift/hardlinks_mod.py \
	backshift/main.py \
	backshift/metadata_mod.py \
	backshift/modunits.py \
	backshift/readline0.py \
	backshift/repo_mod.py \
	backshift/rolling_checksum_py_mod.py \
	backshift/saveset_files_mod.py \
	backshift/saveset_summary_mod.py \
	backshift/xz_mod.py \
	bin/backshift \
	treap/py_treap_node.py \
	treap/py_treap.py \
	treap/treap.py

# These are all files with things that pylint hates, even with the weird workarounds I've tried - keep'em small!
# Why?  Mostly because of the module renames from Python 2.x to 3.x
no_pylint_files=treap/treap.py backshift/python2x3.py backshift/stringio.py backshift/db_mod.py backshift/rolling_checksum_mod.py

all_py_files=$(pylint_files) $(no_pylint_files)

first-rule: prep static-analysis unit-tests system-tests
	true

prep: treap/treap.py backshift/rolling_checksum_py_mod.py tags
	true

treap/treap.py treap/py_treap.py treap/py_treap_node.py: treap/m4_treap.m4
	cd treap; make py_treap.py py_treap_node.py #; cp treap.py py_treap.py py_treap_node.py ../backshift/.

unit-tests: \
	test-cacher_mod.uto \
	test-compressed_file_mod.2.uto \
	test-compressed_file_mod.3.uto \
	test-dohdbm.uto \
	test-escape_mod.2.uto \
	test-escape_mod.3.uto \
	test-rolling_checksum_py_mod.uto
	true

pick:
	./this-pylint pick-rolling_checksum
	./pick-rolling_checksum

tags: $(all_py_files)
	ctags-exuberant $(all_py_files) || true

static-analysis: $(pylint_files)
	./this-pylint $(pylint_files)
	./this-pep8 $(pylint_files)

system-tests: $(all_py_files)
	cd tests; make

rcm-input-data:
	./gen-rcm-input-data > rcm-input-data

test-compressed_file_mod.2.uto: test-compressed_file_mod compressed_file_mod.py
	./this-pylint test-compressed_file_mod compressed_file_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-a --args test-compressed_file_mod 2>&1 | tee test-compressed_file_mod.2.uto'

test-compressed_file_mod.3.uto: test-compressed_file_mod compressed_file_mod.py
	./this-pylint test-compressed_file_mod compressed_file_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-b --args test-compressed_file_mod 2>&1 | tee test-compressed_file_mod.3.uto'

test-rolling_checksum_py_mod.uto: rcm-input-data test-rolling_checksum_mod backshift/rolling_checksum_py_mod.py
	./this-pylint test-rolling_checksum_mod backshift/rolling_checksum_py_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety fast --args test-rolling_checksum_mod py 2>&1 3>&2 | tee test-rolling_checksum_py_mod.uto'

test-rolling_checksum_pyx_mod.2.uto: rcm-input-data test-rolling_checksum_mod backshift/rolling_checksum_py_mod.py
	./this-pylint test-rolling_checksum_mod backshift/rolling_checksum_py_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-a --args test-rolling_checksum_mod pyx 2>&1 3>&2 | tee test-rolling_checksum_pyx_mod.2.uto'

test-rolling_checksum_pyx_mod.3.uto: rcm-input-data test-rolling_checksum_mod backshift/rolling_checksum_py_mod.py
	./this-pylint test-rolling_checksum_mod backshift/rolling_checksum_py_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-b --args test-rolling_checksum_mod pyx 2>&1 3>&2 | tee test-rolling_checksum_pyx_mod.3.uto'

test-cacher_mod.uto: test-cacher_mod cacher_mod.py
	./this-pylint test-cacher_mod cacher_mod.py
	./run-ut cacher_mod
	rm -f *.doh

test-dohdbm.uto: test-dohdbm dohdbm.py
	./this-pylint test-dohdbm dohdbm.py
	./run-ut dohdbm
	rm -f *.doh

test-escape_mod.2.uto: test-escape_mod escape_mod.py
	./this-pylint test-escape_mod escape_mod.py
	if ! ./this-interpreter --variety minimal-a --args test-escape_mod > test-escape_mod.2.uto 2>&1; then cat test-escape_mod.2.uto; exit 1; fi

test-escape_mod.3.uto: test-escape_mod escape_mod.py
	./this-pylint test-escape_mod escape_mod.py
	if ! ./this-interpreter --variety minimal-b --args test-escape_mod > test-escape_mod.3.uto 2>&1; then cat test-escape_mod.3.uto; exit 1; fi

rcms: test-rolling_checksum_py_mod.uto rolling_checksum_pyx_mod.pyx
	#gcc -O3 -c -I/usr/local/cpython-$$pyvers/include/python$$pyvers rolling_checksum_pyx_mod.c; \
	#gcc -shared rolling_checksum_pyx_mod.o -o rolling_checksum_pyx_mod.so; \
	#
	set -xeu; \
	for pyvers in 2.5 2.6 2.7 3.0 3.1 3.2; \
	do \
		rm -f rolling_checksum_pyx_mod.c; \
		rm -f rolling_checksum_pyx_mod.o; \
		rm -f rolling_checksum_pyx_mod.so; \
		/usr/local/cpython-$$pyvers/bin/python \
			/usr/local/cpython-$$pyvers/bin/cython \
			rolling_checksum_pyx_mod.pyx; \
		gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC \
			-I/usr/local/cpython-$$pyvers/include/python$$pyvers -c rolling_checksum_pyx_mod.c; \
		gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions rolling_checksum_pyx_mod.o \
			-o rolling_checksum_pyx_mod.so; \
		cp rolling_checksum_pyx_mod.so /usr/local/cpython-$$pyvers/lib/python$$pyvers/site-packages/.; \
	done
	rm -f rolling_checksum_pyx_mod.so
	make test-rolling_checksum_pyx_mod.2.uto 
	make test-rolling_checksum_pyx_mod.3.uto 
	touch rcms
#		gcc -shared rolling_checksum_pyx_mod.o -o rolling_checksum_pyx_mod.so \
#			-L/usr/local/cpython-$$pyvers/lib/python$$pyvers/config \
#			-lpython$$pyvers; \
#

backshift/rolling_checksum_py_mod.py: rolling_checksum_mod.m4
	m4 -Dpy=1 rolling_checksum_mod.m4 > backshift/rolling_checksum_py_mod.py

rolling_checksum_pyx_mod.pyx: rolling_checksum_mod.m4
	m4 -Dpyx=1 rolling_checksum_mod.m4 > rolling_checksum_pyx_mod.pyx

publish: documentation
	[ `hostname` = server ] || exit 1
	rsync -apl --delete doc/. ~/public_html/backshift/documentation/.
	#(cd doc && tar cflS - .) | (cd ~/public_html/backshift/documentation && tar xfp -)

documentation: $(all_py_files) rolling_checksum_pyx_mod.pyx doc/profile-rcm.pdf
	# snakefood for an import graph
	sfood ${all_py_files} | sfood-graph > doc/imports.dot
	dot -Tpdf doc/imports.dot > doc/imports.pdf
	# pyreverse for package and class diagrams
	PYTHONPATH=$$(pwd) pyreverse -f ALL -a1 -s1 -p backshift ${all_py_files}
	mv packages_backshift.dot doc/.
	mv classes_backshift.dot doc/.
	dot -Tpdf doc/packages_backshift.dot > doc/packages_backshift.pdf
	dot -Tpdf doc/classes_backshift.dot > doc/classes_backshift.pdf
	epydoc --graph all --docformat=plaintext ${all_py_files}
	rm -rf doc/html
	mv html doc/.
	./this-interpreter --variety just-a-cython --args -a rolling_checksum_pyx_mod.pyx
	mv rolling_checksum_pyx_mod.html doc/.

doc/profile-rcm.pdf: rcm-input-data rolling_checksum_py_mod.py profile-rcm
	./this-pylint profile-rcm rolling_checksum_py_mod.py
	./this-interpreter --variety minimal-a --args profile-rcm
	gprof2dot -f pstats profile-rcm.pstats | dot -Tpdf -o doc/profile-rcm.pdf || true
	
clean:
	rm -f *.pdf input-file output-file *.o *.so *.pyc *-pylint.html tags *.class *.uto
	cd treap && make clean
	rm -f *\$$py.class # for Jython
	cd tests; make clean
	cd treap; make veryclean
	rm -rf backshift/__pycache__
	rm -f rcms
	rm -f rcm-input-data
	# these are automatically generated from a _mod.m4 file
	rm -f backshift/*_py_mod.py
	rm -f backshift/rolling_checksum_pyx_mod.pyx
	rm -f backshift/rolling_checksum_pyx_mod.c
	rm -f *.dot *.ps *.pdf doc/*.dot doc/*.ps doc/*.pdf
	rm -rf html doc/html
	rm -f bin/backshiftc
	rm -f doc/rolling_checksum_pyx_mod.html
	rm -f test-file.rm-me
	rm -f *.doh
	rm -f @testfile
	chmod +rwx readonly-directory 2> /dev/null || true; rm -rf readonly-directory
	rm -f *.pstats