VERSION ?= 1.3.1
PYPI_VERSION ?= $(VERSION)
RELEASE_TAG ?= v$(VERSION)
ARTIFACT_VERSION ?= $(RELEASE_TAG)
RELEASE_BASE_URL ?= https://trylle.com/trylle/trylle-cli/releases/download

ROOT_DIR := $(abspath ..)
OUTPUT_DIR ?= $(CURDIR)/output
BINARIES_DIR ?= $(CURDIR)/binaries
DOCKERFILE := $(ROOT_DIR)/packaging/Dockerfile
CONTEXT := $(ROOT_DIR)

.PHONY: help check-docker check-binaries clean npm-build npm-build-base \
	npm-build-platforms npm-publish npm-publish-unscoped npm-publish-scoped \
	pypi-build pypi-publish all-build all-publish

help:
	@echo "Trylle CLI registry packaging"
	@echo ""
	@echo "  make all-build VERSION=1.0.0-beta.6 PYPI_VERSION=1.0.0b6"
	@echo "  make npm-publish NPM_TOKEN=..."
	@echo "  make pypi-publish PYPI_TOKEN=..."

check-docker:
	@docker buildx version >/dev/null

check-binaries:
	@for binary in \
		trylle-cli-darwin-arm64 \
		trylle-cli-linux-arm64 \
		trylle-cli-linux-x64; do \
		test -f "$(BINARIES_DIR)/$$binary" || { \
			echo "Missing $(BINARIES_DIR)/$$binary" >&2; \
			exit 1; \
		}; \
	done

define export_build
	@tmp="$(OUTPUT_DIR)/.$(1)"; \
	rm -rf "$$tmp"; \
	docker buildx build \
		--file "$(DOCKERFILE)" \
		--target "$(2)" \
		--output "type=local,dest=$$tmp" \
		$(3) \
		"$(CONTEXT)"; \
	mkdir -p "$(OUTPUT_DIR)"; \
	cp -R "$$tmp"/. "$(OUTPUT_DIR)"/; \
	rm -rf "$$tmp"
endef

npm-build-base: check-docker
	$(call export_build,npm-base,npm-base-output,\
		--build-arg NODE_VERSION=$(VERSION) \
		--build-arg RELEASE_TAG=$(RELEASE_TAG) \
		--build-arg ARTIFACT_VERSION=$(ARTIFACT_VERSION) \
		--build-arg RELEASE_BASE_URL=$(RELEASE_BASE_URL))

define npm_platform_build
	$(call export_build,npm-$(1),npm-platform-output,\
		--build-arg PLATFORM=$(1) \
		--build-arg NODE_OS=$(2) \
		--build-arg NODE_ARCH=$(3) \
		--build-arg NODE_VERSION=$(VERSION))
endef

npm-build-darwin-arm64: check-docker check-binaries
	$(call npm_platform_build,darwin-arm64,darwin,arm64)

npm-build-linux-arm64: check-docker check-binaries
	$(call npm_platform_build,linux-arm64,linux,arm64)

npm-build-linux-x64: check-docker check-binaries
	$(call npm_platform_build,linux-x64,linux,x64)

npm-build-platforms: npm-build-darwin-arm64 npm-build-linux-arm64 npm-build-linux-x64
npm-build: npm-build-base npm-build-platforms

define pypi_platform_build
	$(call export_build,pypi-$(1),pypi-output,\
		--build-arg PYPI_PLATFORM=$(2) \
		--build-arg VERSION=$(PYPI_VERSION))
endef

pypi-build-darwin-arm64: check-docker check-binaries
	$(call pypi_platform_build,darwin-arm64,macosx_11_0_arm64)

pypi-build-linux-arm64: check-docker check-binaries
	$(call pypi_platform_build,linux-arm64,manylinux_2_17_aarch64)

pypi-build-linux-x64: check-docker check-binaries
	$(call pypi_platform_build,linux-x64,manylinux_2_17_x86_64)

pypi-build: pypi-build-darwin-arm64 pypi-build-linux-arm64 pypi-build-linux-x64
all-build: npm-build pypi-build

npm-publish-unscoped: npm-build
	@NODE_AUTH_TOKEN="$(NPM_TOKEN)" ./scripts/publish-npm.sh unscoped "$(OUTPUT_DIR)/npm"

npm-publish-scoped: npm-build
	@NODE_AUTH_TOKEN="$(NPM_TOKEN)" ./scripts/publish-npm.sh scoped "$(OUTPUT_DIR)/npm"

npm-publish: npm-publish-unscoped npm-publish-scoped

pypi-publish: pypi-build
	@docker run --rm \
		-v "$(OUTPUT_DIR)/pypi:/packages:ro" \
		-e TWINE_USERNAME=__token__ \
		-e TWINE_PASSWORD="$(PYPI_TOKEN)" \
		python:3.12-slim \
		sh -c 'pip install --quiet twine==7.0.0 && twine check /packages/*.whl && twine upload --skip-existing /packages/*.whl'

all-publish: npm-publish pypi-publish

clean:
	rm -rf "$(OUTPUT_DIR)"
