# Kindly Flutter SDK — local release Makefile
#
# Releases are run by hand from a developer laptop (we publish infrequently);
# there is no GitHub Actions / Jenkins pipeline for this package.
#
# Typical flows:
#   make setup        # one-time tool install (Homebrew, Ansible, gtimeout)
#   make bundle       # build-only: refresh the iOS xcframework + Android AAR
#                     # (publish-to-pubdev.yml does this automatically too;
#                     # use `make bundle` for stand-alone build verification)
#   make publish-dry  # bundle + validate on pub.dev, WITHOUT uploading
#   make publish      # bundle + validate + confirmation + upload + tag + bump
#
# See scripts/README.md for the playbook details, and the project plan in
# /Users/alexy/.claude/plans/ for the rationale behind this layout.

# ---------------------------------------------------------------------------
# Variables (override on the command line, e.g. `make bundle DRY_RUN=true`)
# ---------------------------------------------------------------------------
PROJECT_DIR         ?= $(PWD)
IOS_PROJECT_DIR     ?= $(abspath $(PROJECT_DIR)/../ios-source)
ANDROID_PROJECT_DIR ?= $(abspath $(PROJECT_DIR)/../android-source)
APPLE_TEAM_ID       ?= G2P4AFMWD6

DRY_RUN             ?= true
SKIP_TESTS          ?= false
SKIP_ANALYSIS       ?= false
# AUTO_CONFIRM=true bypasses the interactive confirmation prompt before
# the irreversible upload. Use only for non-interactive contexts (no TTY,
# CI). Default leaves the prompt on so manual operators stay safe.
AUTO_CONFIRM        ?= false

ANSIBLE             ?= ansible-playbook

.PHONY: help setup bundle publish-dry publish format analyze test \
        clean preflight-cert

help:
	@echo "Kindly Flutter SDK — release targets"
	@echo ""
	@echo "  setup        Install / verify Homebrew, Ansible, gtimeout"
	@echo "  bundle       Build + sign xcframework and Android AAR (build-only)"
	@echo "  publish-dry  Bundle + validate on pub.dev (no upload)"
	@echo "  publish      Bundle + validate + confirm + upload + tag + bump"
	@echo ""
	@echo "  format       Run 'dart format' across lib/, test/, example/lib/"
	@echo "  analyze      Run 'flutter analyze'"
	@echo "  test         Run 'flutter test'"
	@echo "  clean        Remove .dart_tool/, build/, example/build/"
	@echo ""
	@echo "Variables:"
	@echo "  IOS_PROJECT_DIR     ($(IOS_PROJECT_DIR))"
	@echo "  ANDROID_PROJECT_DIR ($(ANDROID_PROJECT_DIR))"
	@echo "  APPLE_TEAM_ID       ($(APPLE_TEAM_ID))"

# ---------------------------------------------------------------------------
# Helper: scripts/run.sh wraps any command, sources .env, and (if
# KINDLY_PUB_SA_JSON_B64 is set in .env) decodes it to a temp file
# and exports GOOGLE_APPLICATION_CREDENTIALS. Trapped cleanup removes
# the temp file on success, failure, or interrupt.
#
# Each Make target that needs auth runs through this. (We can't just
# source .env in a separate Make recipe line because each line runs
# in its own subshell — env exports wouldn't reach the next line.)
# ---------------------------------------------------------------------------
RUN := $(PROJECT_DIR)/scripts/run.sh

# ---------------------------------------------------------------------------
# Setup — minimal (we don't need Java/Ruby/Fastlane/Jazzy here, only Ansible).
# ---------------------------------------------------------------------------
setup:
	@echo "🔧 Setting up Flutter SDK build environment..."
	@if ! command -v brew >/dev/null 2>&1; then \
		echo "❌ Homebrew not found. Install from https://brew.sh"; exit 1; \
	fi
	@if ! command -v ansible-playbook >/dev/null 2>&1; then \
		echo "🔹 Installing Ansible..."; brew install ansible; \
	else \
		echo "✅ Ansible: $$(ansible --version | head -1)"; \
	fi
	@if ! command -v gtimeout >/dev/null 2>&1; then \
		echo "🔹 Installing coreutils (for gtimeout)..."; brew install coreutils; \
	else \
		echo "✅ gtimeout available"; \
	fi
	@if ! command -v xcodebuild >/dev/null 2>&1; then \
		echo "❌ xcodebuild not found. Install Xcode from the App Store, then run sudo xcode-select --install"; \
		exit 1; \
	else \
		echo "✅ Xcode: $$(xcodebuild -version | head -1)"; \
	fi
	@if ! command -v flutter >/dev/null 2>&1; then \
		echo "❌ flutter not found in PATH"; exit 1; \
	else \
		echo "✅ Flutter: $$(flutter --version | head -1)"; \
	fi
	@echo "🎉 Setup complete."

# ---------------------------------------------------------------------------
# Cert preflight — fail fast before the 20-minute iOS archive starts.
# ---------------------------------------------------------------------------
preflight-cert:
	@if security find-identity -v -p codesigning | grep -q "Apple Distribution.*$(APPLE_TEAM_ID)"; then \
		echo "✅ Apple Distribution cert for team $(APPLE_TEAM_ID) is in the keychain."; \
	else \
		echo ""; \
		echo "❌ No Apple Distribution certificate found for team $(APPLE_TEAM_ID)."; \
		echo "   The bundled xcframework needs this cert to pass App Store ITMS-91065."; \
		echo ""; \
		echo "   Fix: from $(IOS_PROJECT_DIR), run:"; \
		echo "     bundle exec fastlane match development --readonly"; \
		echo ""; \
		echo "   You usually do this for normal iOS releases — same setup applies here."; \
		exit 1; \
	fi

# ---------------------------------------------------------------------------
# Bundle — drives scripts/bundle-native-sdks.yml. Produces:
#   ios/Frameworks/Kindly.xcframework  (signed with Apple Distribution)
#   android/libs/kindlysdk.aar
# ---------------------------------------------------------------------------
bundle: setup preflight-cert
	@echo "📦 Bundling native SDKs into the Flutter plugin..."
	$(RUN) $(ANSIBLE) $(PROJECT_DIR)/scripts/bundle-native-sdks.yml \
		-e "flutter_project_dir=$(PROJECT_DIR)" \
		-e "ios_project_dir=$(IOS_PROJECT_DIR)" \
		-e "android_project_dir=$(ANDROID_PROJECT_DIR)" \
		-e "apple_team_id=$(APPLE_TEAM_ID)"

# ---------------------------------------------------------------------------
# Publish — single playbook run that internally:
#   1. imports bundle-native-sdks.yml (build + sign xcframework + AAR)
#   2. runs `dart pub publish --dry-run` validation
#   3. (real mode only) prompts for confirmation
#   4. (real mode only) commits the freshly-bundled binaries
#   5. (real mode only) runs `dart pub publish --force`
#   6. (real mode only) tags v$VERSION + bumps pubspec patch + pushes
#
# `publish-dry` short-circuits after step 2; `publish` runs the whole flow.
# Both bundle exactly once. There is no Makefile-level orchestration of
# bundle / dry-run / publish — the playbook owns it.
# ---------------------------------------------------------------------------
publish-dry: setup preflight-cert
	@echo "🔍 Validating package (dry run; bundles native SDKs first)..."
	$(RUN) $(ANSIBLE) $(PROJECT_DIR)/scripts/publish-to-pubdev.yml \
		-e "flutter_project_dir=$(PROJECT_DIR)" \
		-e "ios_project_dir=$(IOS_PROJECT_DIR)" \
		-e "android_project_dir=$(ANDROID_PROJECT_DIR)" \
		-e "apple_team_id=$(APPLE_TEAM_ID)" \
		-e "dry_run=true" \
		-e "skip_tests=$(SKIP_TESTS)" \
		-e "skip_analysis=$(SKIP_ANALYSIS)"

publish: setup preflight-cert
	@echo "🚀 Publishing to pub.dev (bundles, validates, prompts, uploads)..."
	$(RUN) $(ANSIBLE) $(PROJECT_DIR)/scripts/publish-to-pubdev.yml \
		-e "flutter_project_dir=$(PROJECT_DIR)" \
		-e "ios_project_dir=$(IOS_PROJECT_DIR)" \
		-e "android_project_dir=$(ANDROID_PROJECT_DIR)" \
		-e "apple_team_id=$(APPLE_TEAM_ID)" \
		-e "auto_confirm=$(AUTO_CONFIRM)" \
		-e "dry_run=false" \
		-e "skip_tests=$(SKIP_TESTS)" \
		-e "skip_analysis=$(SKIP_ANALYSIS)"

# ---------------------------------------------------------------------------
# Local dev convenience
# ---------------------------------------------------------------------------
format:
	@dart format lib/ test/ example/lib/

analyze:
	@flutter analyze

test:
	@flutter test

clean:
	@rm -rf .dart_tool build example/build example/.dart_tool
	@echo "✅ Cleaned build artefacts (xcframework + AAR are kept — run 'make bundle' to refresh)."
