#!/usr/bin/make -f

include /usr/share/dpkg/pkg-info.mk

#export DH_VERBOSE=1

# If we're doing a pre-release, then be less strict about test failures, etc
ifneq (,$(filter $(DEB_DISTRIBUTION),UNRELEASED unstable-sage))
is_prerelease = true
else
is_prerelease = false
# some buildds are a bit slow
export SAGE_TIMEOUT_LONG = 3600
endif

# Use ccache if pkg.sagemath.ccache build-profile is active.
# Your rebuilds will be *much quicker*.
ifneq (,$(filter pkg.sagemath.ccache,$(DEB_BUILD_PROFILES)))
export PATH := /usr/lib/ccache:$(PATH)
export CCACHE_DIR := $(CURDIR)/debian/ccache
export CCACHE_BASEDIR := $(CURDIR)/debian/build
$(shell mkdir -p "$(CCACHE_DIR)")
endif

export SAGE_LOCAL = $(CURDIR)/debian/build/usr
export PYTHONPATH = $(CURDIR)/debian/build/usr/lib/python2.7/dist-packages
export DOT_SAGE = $(CURDIR)/debian/test

LANGS = $(shell cd sage/src/doc && find . -mindepth 1 -maxdepth 1 -type d | grep -v common | cut -b3-)
DOCS_INSTALL = $(LANGS:%=debian/sagemath-doc-%.install)
DOCS_CONTROL = $(LANGS:%=debian/sagemath-doc-%.control)
DOCS_DOC_BASE = $(LANGS:%=debian/sagemath-doc-%.doc-base)

ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
else
NUMJOBS = 1
endif

%:
	dh $@ --with=python2,sphinxdoc

binary build clean install: debian/control

export-build-env:
	@echo export SAGE_LOCAL=$(SAGE_LOCAL)
	@echo export PYTHONPATH=$(PYTHONPATH)
	@echo export DOT_SAGE=$(DOT_SAGE)

debian/control: debian/control.in $(DOCS_CONTROL)
	cat $^ > "$@"
	sed -i -e '/RUNTIME_DEPENDS/ {' -e 'r debian/control.runtime-depends' -e 'd' -e '}' "$@"
	sed -i -e '/JUPYTER_DEPENDS/ {' -e 'r debian/control.jupyter-depends' -e 'd' -e '}' "$@"

debian/sagemath-doc-%.control: debian/sagemath-doc-LANG.control.in debian/rules
	sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' < "$<" > "$@"

debian/sagemath-doc-%.install: debian/sagemath-doc-LANG.install.in debian/rules
	sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' < "$<" > "$@"

debian/sagemath-doc-en.doc-base: debian/sagemath-doc-LANG.doc-base.in debian/rules
	sed -e "s/LANGUAGE/$$(debian/lang.py en)/g" -e 's/LANG/en/g' -e 's/SUBDIR//g' < "$<" > "$@"

debian/sagemath-doc-ca.doc-base: debian/sagemath-doc-LANG.doc-base.in debian/rules
	sed -e "s/LANGUAGE/$$(debian/lang.py ca)/g" -e 's/LANG/ca/g' -e 's/SUBDIR/intro\//g' < "$<" > "$@"

debian/sagemath-doc-%.doc-base: debian/sagemath-doc-LANG.doc-base.in debian/rules
	if [ "$*" = "hu" -o "$*" = "it" -o "$*" = "tr" ]; then \
		sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' -e 's/SUBDIR/a_tour_of_sage\//g' < "$<" > "$@"; \
	else \
		sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' -e 's/SUBDIR/tutorial\//g' < "$<" > "$@"; \
	fi

prune: debian/control
	cd debian/pruner && autoconf -I m4
	cd debian/pruner && ./configure --with-sage-root="$(CURDIR)/sage"
	cd sage && python ../debian/pruner/pruner.py || $(is_prerelease)
	touch prune

ifneq (,$(filter nodoc,$(DEB_BUILD_OPTIONS)))
DEB_BUILD_TARGET = build
else
DEB_BUILD_TARGET = all
endif
dh_auto_build-stamp: prune
	MAKE='make -j$(NUMJOBS)' make --directory=sage $(DEB_BUILD_TARGET)
	touch dh_auto_build-stamp

check-dochtml-log:
	# Sometimes, parts of the docbuild fail with MemoryError or OSError but
	# Sage doesn't detect this. Here we detect it and fail the build if so.
	! grep Error sage/logs/dochtml.log

# We build everything in both -arch and -indep because the tests need the docs.
# TODO: as described in #849150, we can make this more efficient if we figure
# out how to disable the tests that need the docs.
override_dh_auto_build-arch: dh_auto_build-stamp
# Only run check-dochtml-log if we will actually build the doc packages.
# Otherwise we get spurious failures on some low-memory arch-any buildds.
override_dh_auto_build-indep: dh_auto_build-stamp check-dochtml-log

LOGFILE = sage/logs/ptestlong.log
run_tests = cd sage && ./sage -t -p $(NUMJOBS) --all --long --logfile=logs/ptestlong.log
override_dh_auto_test:
	cd sage && $(SAGE_LOCAL)/bin/sage-starts
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
	# We do the below instead of `$(MAKE) --directory=sage ptestlong` because
	# it has a bug where it can't detect a previous successful build. So it
	# will try to rebuild some sagelib files, then the docbuild, then those
	# files again, even after a "make all" that was previously successful. This
	# is not incorrect, but is a massive waste of time. OTOH debhelper is able
	# to detect a previous successful (override_)dh_auto_build, so if we run
	# `debian/rules build` twice it will go directly to (override_)dh_auto_test
	# (and then this target) without trying (override_)dh_auto_build again.
	$(run_tests) || true
	# If tests fail but not by too many more, then retry them once not in parallel
	# i386 seems to have issues running parallel tests - TODO: investigate this in more detail
	if $(is_prerelease); then :; \
	elif debian/rules -s had-few-failures; then :; else \
	  debian/rules -s had-not-too-many-failures && \
	  mv $(LOGFILE) $(LOGFILE).1 && \
	  { $(run_tests) -f -p 1; cd "$(CURDIR)" && debian/rules -s had-few-failures; }; \
	fi
endif

TESTS_MK = $(MAKE) -s --no-print-directory -f debian/tests.mk LOGFILE=$(LOGFILE)
failed-tests%:
	@$(TESTS_MK) "$@"

ifeq (i386,$(shell dpkg-architecture -q DEB_HOST_ARCH))
IGNORE_FAILURES = | sed -e '0,/Timed out/{//d;}' -e '0,/Timed out/{//d;}' -e '0,/Timed out/{//d;}'
else
IGNORE_FAILURES =
endif
had-few-failures:
	test -f $(LOGFILE)
	test "$$($(TESTS_MK) failed-tests-total-normal)" -lt 80
	test -z "$$($(TESTS_MK) failed-tests-special $(IGNORE_FAILURES))"

had-not-too-many-failures:
	test -f $(LOGFILE)
	test "$$($(TESTS_MK) failed-tests-total-normal)" -lt 120

check-failed:
	$(run_tests) -f

override_dh_auto_install:
	rm -rf debian/build/usr/var/tmp/sage/build
# We built .pyo to make the docbuild/tests go faster, but as per Debian policy
# we don't distribute them.
	find debian/build '(' -name '*.pyc' -o -name '*.pyo' ')' -delete
	rm -f debian/build/usr/bin/*.bat
	cp -f debian/adhoc/sage-env debian/build/usr/bin/
	mkdir -p debian/tmp
	mv debian/build/* debian/tmp
# Don't try to rmdir debian/build if it's a mountpoint, useful for doing builds in /run/shm
	mountpoint debian/build || rmdir debian/build

# If we see "nodoc", don't clean the docs. This allows us to rebuild just the
# non-docs without wiping away the docs we previously built, to save time.
override_dh_auto_clean:
ifneq (,$(filter nodoc,$(DEB_BUILD_OPTIONS)))
	dh_auto_clean -Dsage -- -k clean sagelib-clean misc-clean || true
else
	dh_auto_clean -Dsage -- distclean
endif
	rm -rf sage/config
	rm -f sage/build/make/Makefile-auto.in
	rm -f sage/configure
	rm -f sage/src/Makefile

override_dh_install: $(DOCS_INSTALL) $(DOCS_DOC_BASE)
	dh_install --package sagemath-common -X.so
	dh_install --remaining-packages --list-missing

override_dh_python2-arch:
	dh_python2
	dh_numpy --package sagemath # stop lintian complaining at us

override_dh_shlibdeps:
	dh_shlibdeps -l debian/tmp/usr/lib

override_dh_compress:
# We probably don't need to install the pickle/doctree files but let's exempt
# them from compression anyway for now, so the build goes quicker.
	dh_compress -X.pdf -X.pickle -X.doctree

override_dh_sphinxdoc:
# TODO: fix MathJax.js, Sage needs special treatment
# `man dh_sphinxdoc` says symlinking translations.js is not yet supported
# likewise, it seems not to recognise searchtools.js yet
	dh_sphinxdoc -XMathJax.js -Xtranslations.js -Xsearchtools.js

# If we see "nodoc", don't clean the docs. This allows us to rebuild just the
# non-docs without wiping away the docs we previously built, to save time.
ifneq (,$(filter nodoc,$(DEB_BUILD_OPTIONS)))
# Don't delete my precious docs debhelper! They took a whole fucking hour to build!
preserve_docs = \
	set -e; \
	if [ -d $(2)/usr/share/doc ]; then \
		mkdir -p debian/clean-tmp/usr/share; \
		mv -t debian/clean-tmp/usr/share/ $(2)/usr/share/doc; \
	fi; \
	$(1); \
	if [ -d debian/clean-tmp/usr/share/doc ]; then \
		mkdir -p $(2)/usr/share; \
		mv -t $(2)/usr/share/ debian/clean-tmp/usr/share/doc; \
		rm -rf debian/clean-tmp; \
	fi
else
preserve_docs = $(1)
endif
override_dh_clean:
	rm -f $(DOCS_INSTALL) $(DOCS_DOC_BASE)
	rm -rf $(DOT_SAGE)
	$(call preserve_docs,dh_clean,debian/tmp)
	$(call preserve_docs,rm -rf debian/build/*,debian/build)

# If the docbuild fails and you want to try again, you should run this first.
# Otherwise the docbuild gets slower and slower as it re-reads information from
# its build directory. At least that's my (infinity0) impression; I didn't
# investigate this in too much detail yet.
clean-docbuild:
	rm -rf debian/build/usr/share/doc/sagemath

distclean:
	# don't git reset --hard on purpose, so it's easier to test
	git clean -fdx

distclean-sage:
	cd sage; git clean -fdx && git reset --hard HEAD && git submodule update --force

reset: clean clean-docbuild
	QUILT_PATCHES=debian/patches quilt pop -af || true
	debian/rules distclean-sage
	QUILT_PATCHES=debian/patches quilt push -a

build-dep-maint:
	sudo apt-get install --no-install-recommends equivs devscripts git iso-codes python quilt

build-dep: debian/control
	if which aptitude >/dev/null; then sudo mk-build-deps -ir -t 'aptitude -R'; \
	else sudo mk-build-deps -ir; fi

get-orig-source:
	debian/rules ../sagemath_$(DEB_VERSION_UPSTREAM).orig.tar.xz

../sagemath_$(DEB_VERSION_UPSTREAM).orig.tar.xz: .git/modules/sage/HEAD
	cd sage && git archive --prefix=sagemath_$(DEB_VERSION_UPSTREAM)/sage/ \
	  --format=tar HEAD | xz -zf > ../../sagemath_$(DEB_VERSION_UPSTREAM).orig.tar.xz

../sagemath_$(DEB_VERSION).dsc: distclean-sage distclean ../sagemath_$(DEB_VERSION_UPSTREAM).orig.tar.xz debian/control
	dpkg-buildpackage -d -uc -us -S

APT_PIN_PRIORITY = 100
install-apt-sources:
	sudo apt-get install -y apt-transport-https
	for d in deb deb-src; do \
	  echo "$$d https://debian-science.alioth.debian.org/apt sid-sage/"; done \
	  | sudo tee /etc/apt/sources.list.d/deb-sci-sage.list
	sudo apt-key add $(CURDIR)/debian/deb-sci-sage.asc
	printf "Package: *\nPin: release n=sid-sage\nPin-Priority: $(APT_PIN_PRIORITY)\n" \
	  | sudo tee /etc/apt/preferences.d/deb-sci-sage
	sudo apt-get update

# Temporary workarounds that will be removed eventually:
#
# 1 echo "/var/cache/apt/archives /var/cache/apt/archives none rw,bind 0 0" >> /etc/schroot/sbuild/fstab
#   This helps to avoid http errors due to the mirror network being shitty and apt not doing retries
#
# 2 Do the first part of https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=817236#5
#   Sage needs it due to its pexpect etc stuff
release: ../sagemath_$(DEB_VERSION).dsc
	! $(is_prerelease)
	cd .. && sbuild \
	  --build-dep-resolver=aspcud \
	  --build-failed-commands '%SBUILD_SHELL' \
	  $(EXTRA_SBUILD_FLAGS) \
	  "sagemath_$(DEB_VERSION).dsc"

release-experimental: ../sagemath_$(DEB_VERSION).dsc
	$(is_prerelease)
	cd .. && sbuild \
	  --extra-repository='deb http://httpredir.debian.org/debian experimental main' \
	  --chroot-setup-commands='apt-get install -y apt-transport-https' \
	  --extra-repository='deb https://debian-science.alioth.debian.org/apt sid-sage/' \
	  --extra-repository-key=$(CURDIR)/debian/deb-sci-sage.asc \
	  --build-dep-resolver=aspcud \
	  --build-failed-commands '%SBUILD_SHELL' \
	  $(EXTRA_SBUILD_FLAGS) \
	  "sagemath_$(DEB_VERSION).dsc"
