# SwanDesk — convenience targets around xcodegen + xcodebuild.
#
#   make build          — Debug build of the app + privileged helper
#   make build-release  — Release build
#   make run            — Debug build, then open the .app
#   make clean          — xcodebuild clean + remove build/ and generated project
#   make generate       — regenerate SwanDesk.xcodeproj from project.yml
#   make archive        — Release archive
#   make dmg            — Release build + distributable .dmg in build/
#   make notarize       — make dmg, submit to Apple notary service, staple
#   make source-package — GPL "corresponding source" zip next to the .dmg
#   make deploy         — notarized dmg + source zip → DEPLOY_HOST
#   make version        — print the version string the build will use

PROJECT      := SwanDesk.xcodeproj
SCHEME       := SwanDesk
CONFIG       ?= Debug
DERIVED_DATA := build

# OpenSSL + monolithic strongSwan, both built from src/ for the app's deployment
# target and bundled into the app.
OPENSSL_INSTALL    := src/openssl-install
STRONGSWAN_INSTALL := src/strongswan-install

VERSION := $(shell date +%Y).$(shell date +%-m).$(shell git rev-list HEAD --count 2>/dev/null || echo 0)
DMG     := $(DERIVED_DATA)/$(SCHEME)-$(VERSION).dmg

# GPL "complete corresponding source" zip, built next to the .dmg. SwanDesk links
# strongSwan (GPLv2) into the helper, so distributing the binary obliges us to
# make the source available — `deploy` publishes this alongside the .dmg.
SRC_ZIP := $(DERIVED_DATA)/$(SCHEME)-$(VERSION)-src.zip

# Notary keychain profile. Reuses the AppVersionChecker credential (same Apple ID
# + team CXJY846WKU). To use a dedicated one instead, create it once with:
#   xcrun notarytool store-credentials SWANDESK_NOTARY \
#       --apple-id <id> --team-id CXJY846WKU --password <app-specific-password>
# and override on the command line: make deploy NOTARY_PROFILE=SWANDESK_NOTARY
NOTARY_PROFILE ?= YOUR_NOTARY_PROFILE

# Developer ID identity used to sign the .dmg container (the app + helper are
# signed by the Xcode build itself).
SIGN_IDENTITY  ?= Developer ID Application: Juvex Oy (CXJY846WKU)

DEPLOY_HOST  ?= user@example.com
DEPLOY_PATH  ?= /path/to/SwanDesk.dmg

# Where the corresponding-source zip is published — same remote directory as the
# .dmg (defaults to <dmg-dir>/SwanDesk-src.zip). Override on the CLI if needed.
DEPLOY_SRC_PATH ?= $(dir $(DEPLOY_PATH))$(SCHEME)-src.zip

XCBUILD := xcodebuild \
  -project $(PROJECT) \
  -scheme $(SCHEME) \
  -configuration $(CONFIG) \
  -derivedDataPath $(DERIVED_DATA)

PRODUCT := $(DERIVED_DATA)/Build/Products/$(CONFIG)/$(SCHEME).app

.PHONY: build build-release run clean generate archive dmg notarize deploy version openssl strongswan stage-strongswan source-package help

help:
	@echo "Targets:"
	@echo "  generate       — regenerate $(PROJECT) from project.yml"
	@echo "  build          — Debug build (default CONFIG=Debug)"
	@echo "  build-release  — CONFIG=Release"
	@echo "  run            — build then open the .app"
	@echo "  clean          — xcodebuild clean + remove build/ + generated project"
	@echo "  archive        — Release archive into build/$(SCHEME).xcarchive"
	@echo "  dmg            — Release build + $(DMG)"
	@echo "  notarize       — make dmg, notarize with Apple, staple the ticket"
	@echo "  source-package — GPL corresponding-source zip → $(SRC_ZIP)"
	@echo "  deploy         — notarized dmg + source zip → $(DEPLOY_HOST)"
	@echo "  version        — print $(VERSION)"

# The .xcodeproj is generated (gitignored); (re)create it whenever project.yml
# is newer or the project is missing.
generate: $(PROJECT)

$(PROJECT): project.yml
	xcodegen generate --spec project.yml

# Build OpenSSL (for libcrypto) then the monolithic strongSwan, both from src/ for
# the app's deployment target. `make openssl` / `make strongswan` force a rebuild.
openssl: $(OPENSSL_INSTALL)

# Depend on the build script (which carries the version + checksum) so editing it
# — e.g. bumping the OpenSSL version — actually triggers a rebuild instead of
# being skipped because the install dir already exists.
$(OPENSSL_INSTALL): Scripts/build_openssl.sh
	Scripts/build_openssl.sh

# strongSwan links our OpenSSL, so build that first.
strongswan: $(STRONGSWAN_INSTALL)

$(STRONGSWAN_INSTALL): $(OPENSSL_INSTALL) Scripts/build_strongswan.sh
	Scripts/build_strongswan.sh

build: generate $(STRONGSWAN_INSTALL)
	$(XCBUILD) build

build-release:
	$(MAKE) build CONFIG=Release

run: build
	open "$(PRODUCT)"

clean:
	-$(XCBUILD) clean
	rm -rf $(DERIVED_DATA) $(PROJECT)

archive: generate
	xcodebuild \
	  -project $(PROJECT) \
	  -scheme $(SCHEME) \
	  -configuration Release \
	  -archivePath $(DERIVED_DATA)/$(SCHEME).xcarchive \
	  archive

# Manually re-stage + relocate + codesign the bundled strongSwan into an existing
# build product. Normally runs automatically as an app build phase.
stage-strongswan:
	Scripts/stage_strongswan.sh "$(PRODUCT)"

dmg: build-release
	@release_app="$(DERIVED_DATA)/Build/Products/Release/$(SCHEME).app"; \
	  staging="$(DERIVED_DATA)/dmg-staging"; \
	  if [ ! -d "$$release_app" ]; then echo "error: $$release_app not found"; exit 1; fi; \
	  rm -rf "$$staging" "$(DMG)"; \
	  mkdir -p "$$staging"; \
	  cp -RL "$$release_app" "$$staging/"; \
	  ln -s /Applications "$$staging/Applications"; \
	  hdiutil create \
	    -volname "$(SCHEME) $(VERSION)" \
	    -srcfolder "$$staging" \
	    -ov -format UDZO \
	    "$(DMG)"; \
	  rm -rf "$$staging"; \
	  echo "Created $(DMG)"

notarize: dmg
	@set -e; \
	  if [ ! -f "$(DMG)" ]; then echo "error: $(DMG) not found"; exit 1; fi; \
	  echo "Signing dmg with '$(SIGN_IDENTITY)' ..."; \
	  codesign --force --timestamp --sign "$(SIGN_IDENTITY)" "$(DMG)"; \
	  echo "Notarizing $(DMG) (keychain profile: $(NOTARY_PROFILE)) ..."; \
	  xcrun notarytool submit "$(DMG)" --keychain-profile "$(NOTARY_PROFILE)" --wait; \
	  echo "Stapling ticket ..."; \
	  xcrun stapler staple "$(DMG)"; \
	  xcrun stapler validate "$(DMG)"; \
	  echo "Notarized + stapled $(DMG)"

# GPL: package SwanDesk's own corresponding source + build system into
# $(SRC_ZIP), next to the .dmg. The bundled strongSwan/OpenSSL source is not
# redistributed here — README-SOURCE.txt carries a written offer (GPLv2 §3b)
# with each release's exact version + SHA-256. Uses an allowlist + a secret scan
# that aborts if any signing/cert/key material, deploy host, or build artifact
# slips in. Reads src/*.tar.gz only to record their checksums.
source-package:
	@mkdir -p $(DERIVED_DATA)
	Scripts/package_source.sh "$(VERSION)" "$(SRC_ZIP)"

deploy: notarize source-package
	@set -e; \
	  if [ ! -f "$(DMG)" ]; then echo "error: $(DMG) not found"; exit 1; fi; \
	  if [ ! -f "$(SRC_ZIP)" ]; then echo "error: $(SRC_ZIP) not found"; exit 1; fi; \
	  echo "Deploying $(DMG) -> $(DEPLOY_HOST):$(DEPLOY_PATH)"; \
	  scp "$(DMG)" "$(DEPLOY_HOST):$(DEPLOY_PATH)"; \
	  echo "Publishing source $(SRC_ZIP) -> $(DEPLOY_HOST):$(DEPLOY_SRC_PATH)"; \
	  scp "$(SRC_ZIP)" "$(DEPLOY_HOST):$(DEPLOY_SRC_PATH)"; \
	  echo "Deployed SwanDesk $(VERSION) (binary + GPL corresponding source)"

version:
	@echo "$(VERSION)"
