# todo-swift: see README.md.
#
# Everything SwiftPM fetches or compiles stays under .cache/ (sources in
# .cache/swiftpm and .cache/build/checkouts, compiled output in
# .cache/build/<triple>), so `make clean-deps` can remove the compiled
# part without touching any other project.

SHELL := bash
ROOT := $(abspath ../..)
SWIFT := source $(ROOT)/scripts/env.sh && swift
SWIFTPM := --scratch-path .cache/build --cache-path .cache/swiftpm
ARM64_SDK := aarch64-swift-linux-musl
DIRTY := $(shell git status --porcelain -- . 2>/dev/null | grep -q . && echo -dirty)
VERSION ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo dev)$(DIRTY)
MSG ?= todo-swift $(VERSION)

.PHONY: build build-arm64 test clean clean-deps bump unbump deploy generate run

# Embeds the CSS and JS into the binary and stamps the build version.
# Each file is only rewritten when its content changes.
generate:
	@tools/embed.sh $(ROOT)/shared static Sources/TodoApp/Assets.swift
	@mkdir -p .cache
	@printf '// GENERATED by make. The build version /api/version reports.\npublic let buildVersion = "%s"\n' '$(VERSION)' > .cache/Version.swift.new
	@if cmp -s .cache/Version.swift.new Sources/TodoApp/Version.swift; then rm .cache/Version.swift.new; \
		else mv .cache/Version.swift.new Sources/TodoApp/Version.swift; fi

build: generate
	$(SWIFT) build -c release $(SWIFTPM)
	@mkdir -p dist
	cp .cache/build/release/todo dist/app.new && mv dist/app.new dist/app

build-arm64: generate
	$(SWIFT) build -c release $(SWIFTPM) --swift-sdk $(ARM64_SDK) -Xlinker --strip-all
	@mkdir -p dist
	cp .cache/build/$(ARM64_SDK)/release/todo dist/app-linux-arm64.new && mv dist/app-linux-arm64.new dist/app-linux-arm64
	echo '$(VERSION)' > dist/app-linux-arm64.version
	@file dist/app-linux-arm64 | grep -q 'ARM aarch64.*statically linked' \
		|| { echo "dist/app-linux-arm64 is not a static arm64 binary"; file dist/app-linux-arm64; exit 1; }

test: generate
	$(SWIFT) test $(SWIFTPM)

# Runs the local build on 127.0.0.1 for the shared suite.
PORT ?= 8080
run: build
	dist/app --listen 127.0.0.1:$(PORT) --db $${TMPDIR:-/tmp}/todo-swift.db

clean:
	rm -rf dist

# Removes every compiled artifact, ours and the dependencies', and keeps the
# downloaded sources (.cache/swiftpm, .cache/build/checkouts and
# .cache/build/repositories), so the next build compiles everything again.
clean-deps: clean
	@[ ! -d .cache/build ] || find .cache/build -mindepth 1 -maxdepth 1 \
		! -name checkouts ! -name repositories ! -name artifacts ! -name workspace-state.json \
		-exec rm -rf {} +

bump:
	sed -i 's/^let bumpNote = "unbumped"$$/let bumpNote = "bumped"/' Sources/TodoApp/Routes.swift
	grep -q '^let bumpNote = "bumped"$$' Sources/TodoApp/Routes.swift

unbump:
	sed -i 's/^let bumpNote = "bumped"$$/let bumpNote = "unbumped"/' Sources/TodoApp/Routes.swift
	grep -q '^let bumpNote = "unbumped"$$' Sources/TodoApp/Routes.swift

# Ships dist/app-linux-arm64. Build it from a clean commit first: the
# version it reports is that commit's short SHA.
deploy:
	@[ -f dist/app-linux-arm64 ] || { echo "run make build-arm64 first"; exit 1; }
	@case "$(VERSION)" in *-dirty) echo "commit first: the tree has changes"; exit 1;; esac
	@[ "$$(cat dist/app-linux-arm64.version)" = '$(VERSION)' ] \
		|| { echo "dist/app-linux-arm64 wasn't built at $(VERSION); run make build-arm64"; exit 1; }
	carlos deploy --account bfj --app todo-swift --target linux-arm64 --message "$(MSG)" dist/app-linux-arm64
