#!/usr/bin/make -f
#export DH_VERBOSE = 1

export GOCACHE=$(shell mktemp -d /tmp/gocache-XXXX)

WIN_ARCHS := amd64 arm64
WIN_GOFLAGS := -ldflags=-X=github.com/ubuntu/adsys/internal/consts.Version=$(shell dpkg-parsechangelog -S Version) --mod=vendor
export GOFLAGS := $(WIN_GOFLAGS) -buildmode=pie

# PIE on Windows is only supported for amd64
ifeq ($(shell dpkg --print-architecture),amd64)
	WIN_GOFLAGS += -buildmode=pie
endif

# Only build adwatchd on supported architectures
ifneq ($(filter $(shell dpkg --print-architecture),$(WIN_ARCHS)),)
	WINDOWS_BUILD := 1
endif

# Copy in build directory all content to embed
export DH_GOLANG_INSTALL_ALL := 1

# Skip integration tests when building package: they need docker images
# Tests needing sudo will be skipped automatically
export ADSYS_SKIP_INTEGRATION_TESTS=1

# Do not run Rust tests from Golang, as they're run independently via
# dh-cargo, allowing integration with vendored deps, etc...
export ADSYS_SKIP_RUST_TESTS_IN_GOLANG=1

# The following definitions are necessary because of the manual steps
# we need to do to work around some issues with either dh-cargo,
# the wrapper, or cargo
include /usr/share/rustc/architecture.mk
CARGO := /usr/share/cargo/bin/cargo
ADSYS_MOUNT := internal/policies/mount/adsys_mount

# Needed for Rust vendored sources tracking
DH_CARGO_VENDORED_SOURCES := /usr/share/cargo/bin/dh-cargo-vendored-sources
export CARGO_VENDOR_DIR = vendor_rust

%:
	dh $@ --buildsystem=golang --with=golang,apport

override_dh_auto_clean:
	dh_auto_clean
	dh_auto_clean --buildsystem=cargo
	# Create the vendor directory when building the source package
	[ -d vendor/ ] || go mod vendor
	# Some crates are shipped with .a files, which get removed by the helpers during the package build as a safety measure.
	# This results in cargo failing to compile, since the files (which are listed in the checksums) are not there anymore.
	# For those crates, we need to replace their checksum with a more general one that only lists the crate checksum, instead of each file.
	if [ ! -d $(CARGO_VENDOR_DIR)/ ]; then \
		$(CARGO) vendor $(CARGO_VENDOR_DIR); \
		[ ! -e $(DH_CARGO_VENDORED_SOURCES) ] || $(DH_CARGO_VENDORED_SOURCES); \
		\
		[ -e /usr/bin/jq ] || (echo "jq is required to run this script. Try installing it with 'sudo apt install jq'" && exit 1); \
		\
		for dep in $$(ls vendor_rust -1); do \
			checksum_file="vendor_rust/$${dep}/.cargo-checksum.json"; \
			a_files=$$(cat $${checksum_file} | jq '.files | keys | map(select(.|test(".a$$")))'); \
			if [ "$$a_files" = "[]" ]; then \
				continue; \
			fi; \
			pkg_checksum=$$(cat "$${checksum_file}" | jq '.package'); \
			echo "{\"files\": {}, \"package\": $${pkg_checksum}}" >"$${checksum_file}"; \
		done; \
	fi
	# That last line above is to warn whoever's doing the packaging that they
	# need to update the Vendored-Sources field. The initial packaging work
	# didn't include said field since the vendoring is done on the fly.

override_dh_auto_configure:
	dh_auto_configure
	# The following lines basically do the same thing as
	# `dh_auto_configure --buildsystem=cargo`
	# on Kinetic and above, but since we're supporting Jammy as well,
	# we need to do it manually. Note that we don't want to export CARGO_HOME
	# in the global debian/rules as it would interfere with the clean target
	[ ! -e $(DH_CARGO_VENDORED_SOURCES) ] || $(DH_CARGO_VENDORED_SOURCES)
	DEB_HOST_GNU_TYPE=$(DEB_HOST_GNU_TYPE) DEB_HOST_RUST_TYPE=$(DEB_HOST_RUST_TYPE) \
		CARGO_HOME=$(CURDIR)/debian/cargo_home DEB_CARGO_CRATE=adsys_$(shell dpkg-parsechangelog --show-field Version) \
		$(CARGO) prepare-debian $(CARGO_VENDOR_DIR)

override_dh_auto_build:
	# Build on linux only adsysd itself, and not generator or Windows binaries
	DH_GOLANG_BUILDPKG=github.com/ubuntu/adsys/cmd/adsysd dh_auto_build

override_dh_auto_test:
	dh_auto_test --buildsystem=cargo -- test --all
	dh_auto_test

# Build the Windows executables for adwatchd where applicable
ifeq ($(WINDOWS_BUILD),1)
	GOFLAGS="$(WIN_GOFLAGS)" GOOS=windows DH_GOLANG_BUILDPKG=github.com/ubuntu/adsys/cmd/adwatchd dh_auto_build
endif

override_dh_auto_install:
	dh_auto_install -- --no-source

	# Here we utilise a logical flaw in the cargo wrapper to our advantage:
	# when specifying DEB_CARGO_CRATE_IN_REGISTRY=1, the wrapper will
	# avoid adding the `--path` option, so that we can specify it ourselves
	DEB_HOST_GNU_TYPE=$(DEB_HOST_GNU_TYPE) \
	DEB_HOST_RUST_TYPE=$(DEB_HOST_RUST_TYPE) \
	CARGO_HOME=$(CURDIR)/debian/cargo_home \
	DEB_CARGO_CRATE=adsys_mount_0.1.0 \
	DEB_CARGO_CRATE_IN_REGISTRY=1 \
	DESTDIR=$(CURDIR)/debian/tmp \
        $(CARGO) install --path $(ADSYS_MOUNT)
	# Currently doesn't work because of https://github.com/rust-lang/cargo/issues/4101
	# combined with a lack of flexibility in the cargo wrapper. That means we
	# have to do it manually (with the build split out in dh_auto_build for good
	# measure, even though dh-cargo does it all in the install step)
	# dh_auto_install --buildsystem=cargo -- --path $(ADSYS_MOUNT)

	# PAM configuration
	mkdir -p debian/tmp/usr/share/pam
	cp -a pam/pam-configs debian/tmp/usr/share

	# systemd services
	mkdir -p debian/tmp/lib/systemd/system debian/tmp/usr/lib/systemd/user
	cp -a systemd/*.mount debian/tmp/lib/systemd/system/
	cp -a systemd/*.service debian/tmp/lib/systemd/system/
	cp -a systemd/*.socket debian/tmp/lib/systemd/system/
	cp -a systemd/*.timer debian/tmp/lib/systemd/system/
	cp -a systemd/user/*.service debian/tmp/usr/lib/systemd/user/

# Separate windows binaries
ifeq ($(WINDOWS_BUILD),1)
	mkdir -p debian/tmp/usr/share/adsys/windows
	mv debian/tmp/usr/bin/windows_*/* debian/tmp/usr/share/adsys/windows
	rmdir debian/tmp/usr/bin/windows_*

	# Ship admx/adml for ubuntu
	cp -a policies/Ubuntu debian/tmp/usr/share/adsys/windows/policies
endif

	# Install in /sbin
	mv debian/tmp/usr/bin/ debian/tmp/sbin
	# Create adsysctl command
	ln -s adsysd debian/tmp/sbin/adsysctl
	# Run go generate to install assets, but don’t regenerate them
	GENERATE_ONLY_INSTALL_TO_DESTDIR=$(CURDIR)/debian/tmp go generate -x -tags tools $(GOFLAGS) ./...
