# 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

this_pylint_opts=--which-2 None --which-3 /usr/local/cpython-3.9/bin/pylint

pylint_files= \
	backshift \
	backshift_os_mod.py  \
	backshift_file_mod.py  \
	base255.py \
	bloom_filter_mod.py  \
	bufsock.py  \
	cacher_mod.py \
	chunk_mod.py \
	compressed_file_mod.py \
	compressed_string_mod.py \
	constants_mod.py \
	db_mod.py \
	dohdbm.py \
	dirops_mod.py \
	escape_mod.py \
	expire_mod.py \
	file_count_mod.py \
	get_chunk.py \
	hardlinks_mod.py \
	helpers.py \
	main.py \
	metadata_mod.py \
	modunits.py \
	py_treap.py \
	readline0.py \
	repo_mod.py \
	rolling_checksum_mod.py \
	rolling_checksum_py_mod.py \
	saveset_files_mod.py \
	saveset_summary_mod.py \
	stringio.py \
	touch.py \
	treap.py \
	xz_mod.py \
	zst_mod.py \
	zst_zstandard.py

all_py_files=$(pylint_files)

first-rule: prep static-analysis unit-tests system-tests
	echo first-rule done

test-backshift-get-chunk:
	./backshift \
		--save-directory /backshift/save-directory \
		--get-chunk 0000018ccea1e7171b76712d1572e542cfbaff86b7ef5f96855df531da590e04 \
		| sha256sum

prep: treap.py rolling_checksum_py_mod.py tags
	./install-zstandards
	true

treap.py py_treap.py: treap-dir/m4_treap.m4
	cd treap-dir/pure-python; python3 setup.py build; cp treap.py py_treap.py ../..

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

pick:
	./this-pylint ${this_pylint_opts} --to-pylint pick-rolling_checksum
	./pick-rolling_checksum

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

static-analysis: $(pylint_files)
	./this-pylint --which-python-3 /usr/local/cpython-3.7/bin/python3 --which-2 None  --to-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.3.uto: test-compressed_file_mod compressed_file_mod.py
	./this-pylint ${this_pylint_opts} --to-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-compressed_string_mod.3.uto: test-compressed_string_mod compressed_string_mod.py
	./this-pylint ${this_pylint_opts} --to-pylint test-compressed_string_mod compressed_string_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-b --args test-compressed_string_mod 2>&1 | tee test-compressed_string_mod.3.uto'

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

test-rolling_checksum_pyx_mod.3.uto: rcm-input-data test-rolling_checksum_mod rolling_checksum_py_mod.py
	./this-pylint ${this_pylint_opts} --to-pylint test-rolling_checksum_mod 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 --cython 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 ${this_pylint_opts} --to-pylint test-cacher_mod cacher_mod.py
	./run-ut cacher_mod
	rm -f *.doh

test-dohdbm.uto: test-dohdbm dohdbm.py
	./this-pylint ${this_pylint_opts} --to-pylint test-dohdbm dohdbm.py
	./run-ut dohdbm
	rm -f *.doh

test-escape_mod.3.uto: test-escape_mod escape_mod.py
	./this-pylint ${this_pylint_opts} --to-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
	set -xeu; \
	for cpython in $$(set -eu; \
		./this-interpreter --variety all-cpythons | cut -f 2 -d '%'); \
	do \
		if ./build-one-rcm --python "$${cpython}" --install-to-site-packages; \
		then \
			"$${cpython}" ./test-rolling_checksum_mod pyx; \
		fi; \
	done
	rm -f rolling_checksum_pyx_mod.so rolling_checksum_pyx_mod.o
	touch rcms

rolling_checksum_py_mod.py: rolling_checksum_mod.m4
	m4 -Dpy=1 rolling_checksum_mod.m4 > 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

rolling_checksum_pyx_mod.so: rolling_checksum_pyx_mod.pyx
	./build-one-rcm --python "$${cpython}"

# This is for a nuitka build.  It has -not- been thoroughly tested, but seems to work
backshift.exe: $(all_py_files)
	nuitka --python-version=3.3 --exe --recurse-all --show-progress ./backshift

pypi:
	python3 setup.py sdist
	twine upload dist/*
	
test-pypi: clean
	python3 setup.py sdist
	twine upload --repository-url https://test.pypi.org/legacy/ dist/*

publish: documentation
	[ `hostname` = connserv ] || exit 1
	rsync -apl --delete doc/. ~/public_html/backshift/documentation/.

documentation: $(all_py_files) rolling_checksum_pyx_mod.pyx doc/profile-rcm.pdf sphinx-doc
	# snakefood was for an import graph, but it was Python 2.x-only.
	# 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
	# We use sphinx now instead of epydoc, since portions of backshift is Python 3.x-only now.
	# epydoc --graph all --docformat=plaintext ${all_py_files}
	# rm -rf doc/html
	# mv html doc/.
	# without this sed, epydoc produces html/xml that php barfs on with a T_STRING issue.  Silly php.
	# sed -i 's#<?\(xml.*\)?>#<\1>#' doc/html/*.html
	./this-interpreter --variety just-a-cython --args -a rolling_checksum_pyx_mod.pyx
	mv rolling_checksum_pyx_mod.html doc/.
	cd doc/comparison && make
	./doc/give-cc $(all_py_files) > doc/cyclo.html

sphinx-doc: treap.py py_treap.py rolling_checksum_py_mod.py
	[ -d doc ] && [ -f repo_mod.py ]
	rm -rf doc-temp doc/html
	sphinx-apidoc --follow-links --full -H backshift --separate -o doc-temp .
	sed -i "s#^\(SOURCEDIR *= *\).*#\1`pwd`/doc-temp#" doc-temp/Makefile
	touch doc-temp/conf.py
	export PYTHONPATH=`pwd` && cd doc-temp && make html
	[ -f doc-temp/_build/html/index.html ]
	mv doc-temp/_build/html doc/html
	# rm -rf doc-temp

doc/profile-rcm.pdf: rcm-input-data rolling_checksum_py_mod.py profile-rcm
	./this-pylint ${this_pylint_opts} --to-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

tarball: clean prep
	./prepare-tarballs

# We don't always need rolling_checksum_pyx_mod.pyx, but creating it shouldn't hurt, and sometimes we do need it.
install: prep rolling_checksum_pyx_mod.pyx
	./install-file --file backshift-one --directory $$(cat install-variables/bindir-file)/.
	./install-file --file total --directory $$(cat install-variables/bindir-file)/.
	./install-file --file sshfs-backup --directory $$(cat install-variables/bindir-file)/.
	./install-file --file backshift-while --directory $$(cat install-variables/bindir-file)/.
	./install-file --file backshift-verify-filesystem --directory $$(cat install-variables/bindir-file)/.
	./install-file --file backshift-verify-file --directory $$(cat install-variables/bindir-file)/.
	./install-file --file backshift-recent-backup-id --directory $$(cat install-variables/bindir-file)/.
	./install-file --file backshift-extracts --directory $$(cat install-variables/bindir-file)/.
	./install-file --file count --directory $$(cat install-variables/bindir-file)/.
	./install-file --file strip-components --directory $$(cat install-variables/bindir-file)/.
	./perform-install ${all_py_files}

clean:
	rm -f *.pdf input-file output-file *.o *.so *.pyc *-pylint.html tags *.class *.uto treap.py py_treap.py
	rm -f *\$$py.class # for Jython
	cd tests; make clean
	cd treap-dir/pure-python; python3 setup.py clean
	rm -rf __pycache__
	rm -f rcms
	rm -f rcm-input-data
	# these are automatically generated from a _mod.m4 file
	rm -f *_py_mod.py
	rm -f rolling_checksum_pyx_mod.pyx
	rm -f rolling_checksum_pyx_mod.c
	rm -f *.dot *.ps *.pdf doc/*.dot doc/*.ps doc/*.pdf
	rm -f doc/comparison/index.html
	rm -rf html doc/html
	rm -f 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
	rm -rf install-variables
	rm -f doc/cyclo.html
	rm -f zero-length
	rm -rf dist
	rm -rf build
	rm -f MANIFEST
	rm -rf backshift.build
	rm -f backshift.exe
	rm -rf .ropeproject
	rm -rf doc-temp

upload: prep
	python setup.py sdist upload