PREFIX  ?= /usr
DESTDIR ?=
# Rust target triple. Empty builds for this machine, into target/release.
RUST_TARGET ?=

CARGO_FLAGS = --release $(if $(RUST_TARGET),--target $(RUST_TARGET))
RELEASE_DIR = target/$(if $(RUST_TARGET),$(RUST_TARGET)/)release

BINDIR      = $(DESTDIR)$(PREFIX)/bin
APPSDIR     = $(DESTDIR)$(PREFIX)/share/applications
ICONSDIR    = $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps
METAINFODIR = $(DESTDIR)$(PREFIX)/share/metainfo
UNITDIR     = $(DESTDIR)$(PREFIX)/lib/systemd/system
RELAYCONF   = $(DESTDIR)/etc/eydos-prompt-relay
RELAYDOC    = $(DESTDIR)$(PREFIX)/share/doc/eydos-prompt-relay
RENEWHOOKS  = $(DESTDIR)/etc/letsencrypt/renewal-hooks/deploy

LAUNCH      = LTK_THEMES_DIR=$(CURDIR)/../ltk/themes $(CURDIR)/target/release/eydos-prompt

# Android, with Debian's own packages: rustc and rust-src of the same version,
# google-android-ndk-r27c-installer, and ltk's packaging scripts with the
# tools they need (aapt, zipalign, apksigner, android-framework-res).
LTK            ?= /usr/share/cargo/registry/ltk-0.3.0
NDK            ?= /usr/lib/android-sdk/ndk/27.2.12479018
ANDROID_API    ?= 26
ANDROID_TARGET ?= aarch64-linux-android
ANDROID_ABI    ?= arm64-v8a
NDK_BIN         = $(NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin
NDK_CC          = $(NDK_BIN)/$(ANDROID_TARGET)$(ANDROID_API)-clang
TARGET_ENV      = $(subst -,_,$(ANDROID_TARGET))
# freetype-sys builds its own FreeType as C++ on Android; FreeType is C, so no
# C++ library is linked and the APK needs no libc++_shared.so.
ANDROID_ENV     = RUSTC_BOOTSTRAP=1 \
	CC_$(TARGET_ENV)=$(NDK_CC) \
	CXX_$(TARGET_ENV)=$(NDK_CC)++ \
	CXXSTDLIB_$(TARGET_ENV)= \
	AR_$(TARGET_ENV)=$(NDK_BIN)/llvm-ar \
	CARGO_TARGET_$(shell echo $(ANDROID_TARGET) | tr a-z- A-Z_)_LINKER=$(NDK_CC)
ANDROID_ASSETS  = target/android/assets
ANDROID_APK     = target/android/eydos-prompt.apk
# The terminal's face, which src/terminal/fonts.rs looks for among the app's resources.
MONO_FONTS      = /usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf /usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf

# Prompt in a browser, for forge/web: the module and its JavaScript in target/web, as Crate's. The page's resources, the terminal's face among them, are forge/web's to build. wasm-bindgen is the one `make web-tools` builds into target/tools with the installed ltk's script, or one on PATH.
WEB_TARGET    = wasm32-unknown-unknown
WEB_OUT       = target/web
WEB_TOOLS     = target/tools
WASM_BINDGEN ?= $(or $(wildcard $(WEB_TOOLS)/bin/wasm-bindgen),$(shell command -v wasm-bindgen 2>/dev/null))
WEBDIR        = $(DESTDIR)$(PREFIX)/share/eydos-prompt/web

.PHONY: all prep arm64 arm64-deps run start start-desktop test install uninstall install-relay uninstall-relay deb deb-arm64 clean distclean android-apk android-install web web-tools web-deps install-web

all: prep
	cargo build $(CARGO_FLAGS) --workspace

# alacritty_terminal, patched, into vendor/.
prep:
	@scripts/prepare-deps.sh

arm64: export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER = aarch64-linux-gnu-gcc
arm64: export PKG_CONFIG = aarch64-linux-gnu-pkg-config
arm64: export PKG_CONFIG_ALLOW_CROSS = 1
arm64:
	$(MAKE) all RUST_TARGET=aarch64-unknown-linux-gnu

arm64-deps:
	sudo dpkg --add-architecture arm64
	sudo apt-get update
	sudo apt-get install -y crossbuild-essential-arm64 libstd-rust-dev:arm64 libwayland-dev:arm64 libxkbcommon-dev:arm64 libfreetype-dev:arm64 libegl-dev:arm64 libgles2-mesa-dev:arm64

run: all
	$(LAUNCH)

start: all
	$(LAUNCH) --mode mobile

start-desktop: all
	$(LAUNCH) --mode desktop

test: prep
	cargo test --workspace

# An installed ltk keeps its package's timestamps, so cargo cannot tell it changed. Stripping at link time would drop the custom sections wasm-bindgen reads.
web: prep
	@test -n "$(WASM_BINDGEN)" || { echo "No wasm-bindgen; run make web-deps"; exit 1; }
	cargo clean --release --target $(WEB_TARGET) -p ltk
	cargo build --release --target $(WEB_TARGET) -p eydos-prompt --bin eydos-prompt --config profile.release.strip=false
	rm -rf $(WEB_OUT)
	$(WASM_BINDGEN) --target web --no-typescript --out-dir $(WEB_OUT) target/$(WEB_TARGET)/release/eydos-prompt.wasm

# wasm-bindgen-cli at the version the installed ltk pins.
web-tools:
	$(LTK)/scripts/wasm-bindgen-cli.sh $(WEB_TOOLS)

# Debian's std for wasm32, and wasm-bindgen-cli.
web-deps:
	sudo apt-get install -y libstd-rust-dev-wasm32 curl
	$(MAKE) web-tools

# For the eydos-prompt-web package, which forge-web-server serves at /prompt.
install-web:
	install -d $(WEBDIR)
	install -m644 $(WEB_OUT)/* $(WEBDIR)/

# The library as the APK's libmain.so, with the installed default theme and the terminal's face.
android-apk: prep
	@test -x $(NDK_CC) || { echo "No NDK compiler at $(NDK_CC); install google-android-ndk-r27c-installer or set NDK="; exit 1; }
	# An installed ltk keeps its package's timestamps, so cargo cannot tell it changed.
	cargo clean --release --target $(ANDROID_TARGET) -p ltk
	$(ANDROID_ENV) cargo rustc --lib --release --crate-type cdylib -Zbuild-std=std,panic_abort --target $(ANDROID_TARGET)
	EXTRA_FONTS="$(MONO_FONTS)" $(LTK)/scripts/android-assets.sh $(ANDROID_ASSETS)
	ANDROID_ABI=$(ANDROID_ABI) MIN_SDK=$(ANDROID_API) PERMISSIONS=android.permission.INTERNET ICON=res/prompt-app-icon.svg \
		KEEP_ALIVE=1 KEEP_ALIVE_USE="Shares terminals with other computers while in the background" \
		$(LTK)/scripts/android-apk.sh $(ANDROID_APK) target/$(ANDROID_TARGET)/release/libeydos_prompt.so io.eydos.Prompt Prompt $(ANDROID_ASSETS)

android-install: android-apk
	adb install -r $(ANDROID_APK)

install:
	install -Dm755 $(RELEASE_DIR)/eydos-prompt          $(BINDIR)/eydos-prompt
	install -Dm644 data/io.eydos.Prompt.desktop         $(APPSDIR)/io.eydos.Prompt.desktop
	install -Dm644 res/prompt-app-icon.svg              $(ICONSDIR)/io.eydos.Prompt.svg
	install -Dm644 data/io.eydos.Prompt.metainfo.xml    $(METAINFODIR)/io.eydos.Prompt.metainfo.xml

uninstall:
	rm -f $(BINDIR)/eydos-prompt
	rm -f $(APPSDIR)/io.eydos.Prompt.desktop
	rm -f $(ICONSDIR)/io.eydos.Prompt.svg
	rm -f $(METAINFODIR)/io.eydos.Prompt.metainfo.xml

install-relay:
	install -Dm755 $(RELEASE_DIR)/eydos-prompt-relay    $(BINDIR)/eydos-prompt-relay
	install -Dm644 data/eydos-prompt-relay.service      $(UNITDIR)/eydos-prompt-relay.service
	install -Dm644 relay/README.md                      $(RELAYDOC)/README.md
	install -Dm755 data/eydos-prompt-relay.renew        $(RENEWHOOKS)/eydos-prompt-relay
	install -dm755 $(RELAYCONF)

uninstall-relay:
	rm -f $(BINDIR)/eydos-prompt-relay
	rm -f $(UNITDIR)/eydos-prompt-relay.service
	rm -f $(RELAYDOC)/README.md
	rm -f $(RENEWHOOKS)/eydos-prompt-relay

# `deb-arm64` cross-builds the arm64 package from amd64; see `make arm64-deps`.
deb:
	dpkg-buildpackage -us -uc -b

deb-arm64:
	dpkg-buildpackage -us -uc -b -a arm64

clean:
	cargo clean

distclean: clean
	rm -rf vendor
	rm -f Cargo.lock
	dh_clean
