include ../build.env

BUILD_PLATFORM ?= linux/amd64

# Should be the same as upstream version in production
VERSION ?= dev
UBOOT_VERSION ?= v2026.01

# Target kube version
KUBE_VERSION ?= v1.33.3

GIT_REV := $(shell git rev-parse HEAD)

PACKAGES_DIR := packages
BIN_DIR      := bin
OUT_DIR      := out

UBOOT_TAR      := $(PACKAGES_DIR)/uboot-$(UBOOT_VERSION).tar.gz
BUILDINFO_FILE := pkg/buildinfo/buildinfo_gen.go
CRD_PATHS      := ./pkg/apis/...


BUILDX_BUILDER      := container-builder
LOCAL_REGISTRY      := registry
LOCAL_REGISTRY_PORT := 5000

CTL_BUILD_BASE_IMAGE := localhost:5000/monok8s/ctl-build-base:$(VERSION)
CTL_BINARY           := ctl-linux-aarch64-$(VERSION)

DOWNLOAD_PACKAGES_STAMP := $(PACKAGES_DIR)/.download-packages.stamp

$(PACKAGES_DIR):
	mkdir -p $@

$(BIN_DIR):
	mkdir -p $@

$(OUT_DIR):
	mkdir -p $@

# Keep buildinfo host-side since it is just generated source and lets Docker see it in build context.
.buildinfo:
	@mkdir -p $(dir $(BUILDINFO_FILE))
	@printf '%s\n' \
		'package buildinfo' \
		'' \
		'const (' \
		'    Version     = "$(VERSION)"' \
		'    KubeVersion = "$(KUBE_VERSION)"' \
		'    GitRevision = "$(GIT_REV)"' \
		'    Timestamp   = "'$$(TZ=UTC date +%Y%m%d.%H%M%S)'"' \
		')' \
	> $(BUILDINFO_FILE)

ensure-buildx:
	@if ! docker buildx inspect $(BUILDX_BUILDER) >/dev/null 2>&1; then \
		echo "Creating buildx builder $(BUILDX_BUILDER)..."; \
		docker buildx create \
			--name $(BUILDX_BUILDER) \
			--driver docker-container \
			--driver-opt network=host \
			--bootstrap --use; \
	else \
		echo "Using existing buildx builder $(BUILDX_BUILDER)"; \
		docker buildx use $(BUILDX_BUILDER); \
	fi

ensure-registry:
	@if ! docker container inspect $(LOCAL_REGISTRY) >/dev/null 2>&1; then \
		echo "Creating local registry..."; \
		docker run -d \
			--restart=always \
			-p $(LOCAL_REGISTRY_PORT):5000 \
			--name $(LOCAL_REGISTRY) \
			registry:2; \
	else \
		if [ "$$(docker inspect -f '{{.State.Running}}' $(LOCAL_REGISTRY))" != "true" ]; then \
			echo "Starting existing local registry..."; \
			docker start $(LOCAL_REGISTRY); \
		fi; \
	fi

$(DOWNLOAD_PACKAGES_STAMP): docker/download-packages.Dockerfile makefile | $(PACKAGES_DIR)
	docker build \
		-f docker/download-packages.Dockerfile \
		--build-arg UBOOT_VERSION=$(UBOOT_VERSION) \
		--output type=local,dest=./$(PACKAGES_DIR) .
	@touch $@

uboot-tools: $(DOWNLOAD_PACKAGES_STAMP)
	docker buildx build --platform linux/arm64 \
		-f docker/uboot-tools.Dockerfile \
		--build-arg UBOOT_VERSION=$(UBOOT_VERSION) \
		--build-arg UBOOT_TAR=$(UBOOT_TAR) \
		--output type=local,dest=./$(OUT_DIR) .

ctl-build-base: ensure-buildx ensure-registry
	docker buildx build \
		--platform linux/amd64,linux/arm64 \
		-f docker/ctl-build-base.Dockerfile \
		-t $(CTL_BUILD_BASE_IMAGE) \
		--output type=image,push=true,registry.insecure=true .

build-bin: .buildinfo ctl-build-base | $(BIN_DIR)
	docker buildx build \
		--platform $(BUILD_PLATFORM) \
		-f docker/ctl-builder.Dockerfile \
		--build-arg BASE_IMAGE=$(CTL_BUILD_BASE_IMAGE) \
		--build-arg VERSION=$(VERSION) \
		--build-arg TARGETOS=linux \
		--build-arg TARGETARCH=arm64 \
		--output type=local,dest=./$(BIN_DIR) .

build-crds: ctl-build-base | $(OUT_DIR)
	mkdir -p "$(OUT_DIR)/crds"
	docker buildx build \
		--platform $(BUILD_PLATFORM) \
		-f docker/crdgen.Dockerfile \
		--build-arg BASE_IMAGE=$(CTL_BUILD_BASE_IMAGE) \
		--output type=local,dest=./$(OUT_DIR)/crds .

build-agent: build uboot-tools
	docker buildx build \
		--platform linux/arm64 \
		-f docker/ctl-agent.Dockerfile \
		--build-arg VERSION=$(VERSION) \
		--load \
		-t localhost/monok8s/node-control:$(VERSION) .

build-local: .buildinfo | $(BIN_DIR)
	docker buildx build \
		-f docker/ctl-builder-local.Dockerfile \
		--build-arg VERSION=$(VERSION) \
		--build-arg KUBE_VERSION=$(KUBE_VERSION) \
		--build-arg GIT_REV=$(GIT_REV) \
		--output type=local,dest=./$(BIN_DIR) .

run-agent:
	docker run --rm \
		-v "$$(pwd)/out:/work/out" \
		localhost/monok8s/node-control:$(VERSION) \
		agent --env-file /work/out/cluster.env

build: build-bin build-crds

clean:
	-docker image rm localhost/monok8s/node-control:$(VERSION) >/dev/null 2>&1 || true
	rm -rf \
		$(BIN_DIR) \
		$(OUT_DIR)/crds \
		$(BUILDINFO_FILE)

distclean: clean
	rm -rf $(OUT_DIR)

dockerclean:
	@echo "Removing tagged images..."
	- docker rmi \
		localhost/monok8s/ctl-build-base:$(VERSION) \
		localhost/monok8s/node-control:$(VERSION) \
		localhost/monok8s/ctl-builder:$(VERSION) \
		localhost/monok8s/crdgen:$(VERSION) \
		2>/dev/null || true

	@echo "Removing dangling build cache/images..."
	- docker image prune -f
	- docker builder prune -f

pkgclean:
	rm -rf $(PACKAGES_DIR)

all: build build-agent build-local

.PHONY: \
	all clean dockerclean \
	.buildinfo ensure-buildx ensure-registry \
	build build-bin build-crds build-local build-agent \
	uboot-tools run-agent
