.DEFAULT_GOAL=help
.PHONY: clear build linux win darwin release image image-all test help

BINARY_NAME := iptvc
ifeq ($(OS),Windows_NT)
	BINARY_EXT := .exe
else
	BINARY_EXT :=
endif
IMAGE_NAME ?= git.axenov.dev/iptv/iptvc
IMAGE_TAG ?= latest
GOARCH ?= amd64
# Platforms baked into the multi-arch manifest by `make image-all`.
IMAGE_PLATFORMS ?= linux/amd64,linux/arm64

VERSION := $(shell git describe --tags --always --dirty 2>/dev/null | sed 's/^v//' || echo "dev")
COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
LDFLAGS := -s -w -X axenov/iptv-checker/app.VERSION=$(VERSION) -X axenov/iptv-checker/app.COMMIT=$(COMMIT)

REPO_ROOT := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
BIN_DIR := $(REPO_ROOT)/bin

## clear = Remove all compiled binaries
clear:
	@rm -rf $(BIN_DIR)

## build = Build binary for the current host platform
build:
	@OS=$$(go env GOOS); ARCH=$$(go env GOARCH); \
	mkdir -p $(BIN_DIR)/$${OS}_$${ARCH}; \
	CGO_ENABLED=0 GOOS=linux GOARCH=$(GOARCH) \
		go build -trimpath -ldflags="$(LDFLAGS)" -o $(BIN_DIR)/$${OS}_$${ARCH}/$(BINARY_NAME) . ; \
	zip -j $(BIN_DIR)/$${OS}_$${ARCH}/iptvc.zip $(BIN_DIR)/$${OS}_$${ARCH}/$(BINARY_NAME) >/dev/null ; \
	echo "Compiled: $(BIN_DIR)/$${OS}_$${ARCH}/$(BINARY_NAME) (linux/$(GOARCH))"

## linux = Build linux release binary (GOARCH=amd64|arm64)
linux:
	@mkdir -p $(BIN_DIR)/linux_$(GOARCH)
	@CGO_ENABLED=0 GOOS=linux GOARCH=$(GOARCH) \
		go build -trimpath -ldflags="$(LDFLAGS)" -o $(BIN_DIR)/linux_$(GOARCH)/$(BINARY_NAME) .
	@zip -j $(BIN_DIR)/linux_$(GOARCH)/iptvc.zip $(BIN_DIR)/linux_$(GOARCH)/$(BINARY_NAME) >/dev/null
	@echo "Compiled: $(BIN_DIR)/linux_$(GOARCH)/$(BINARY_NAME) (linux/$(GOARCH))"

## win = Build windows release binary (GOARCH=amd64|arm64)
win:
	@mkdir -p $(BIN_DIR)/windows_$(GOARCH)
	@CGO_ENABLED=0 GOOS=windows GOARCH=$(GOARCH) \
		go build -trimpath -ldflags="$(LDFLAGS)" -o $(BIN_DIR)/windows_$(GOARCH)/$(BINARY_NAME).exe .
	@zip -j $(BIN_DIR)/windows_$(GOARCH)/iptvc.zip $(BIN_DIR)/windows_$(GOARCH)/$(BINARY_NAME).exe >/dev/null
	@echo "Compiled: $(BIN_DIR)/windows_$(GOARCH)/$(BINARY_NAME).exe (windows/$(GOARCH))"

## darwin = Build darwin release binary (GOARCH=amd64|arm64)
darwin:
	@mkdir -p $(BIN_DIR)/darwin_$(GOARCH)
	@CGO_ENABLED=0 GOOS=darwin GOARCH=$(GOARCH) \
		go build -trimpath -ldflags="$(LDFLAGS)" -o $(BIN_DIR)/darwin_$(GOARCH)/$(BINARY_NAME) .
	@zip -j $(BIN_DIR)/darwin_$(GOARCH)/iptvc.zip $(BIN_DIR)/darwin_$(GOARCH)/$(BINARY_NAME) >/dev/null
	@echo "Compiled: $(BIN_DIR)/darwin_$(GOARCH)/$(BINARY_NAME) (darwin/$(GOARCH))"

## release = Build all release binaries and zip them
release: clear
	@$(MAKE) -j2 linux GOARCH=amd64
	@$(MAKE) -j2 linux GOARCH=arm64
	@$(MAKE) -j2 win GOARCH=amd64
	@$(MAKE) -j2 win GOARCH=arm64
	@$(MAKE) -j2 darwin GOARCH=amd64
	@$(MAKE) -j2 darwin GOARCH=arm64

## test = Run all tests
test:
	@go test ./...
	@go vet ./...

## image = Build single-arch runtime image (linux/$(GOARCH)) and load it into local Docker
image: linux
	@docker build \
		--build-arg TARGETARCH=$(GOARCH) \
		--tag $(IMAGE_NAME):$(IMAGE_TAG) \
		$(REPO_ROOT)
	@echo "Built image: $(IMAGE_NAME):$(IMAGE_TAG) (linux/$(GOARCH))"

## image-all = Build and push multi-arch manifest to the registry
# Requires all referenced linux binaries to exist in bin/ (build them with `make linux`).
image-all: linux
	@docker buildx build \
		--platform $(IMAGE_PLATFORMS) \
		--tag $(IMAGE_NAME):$(IMAGE_TAG) \
		--push \
		$(REPO_ROOT)
	@echo "Pushed multi-arch image: $(IMAGE_NAME):$(IMAGE_TAG) ($(IMAGE_PLATFORMS))"

## help = Show this message and exit
help: Makefile
	@echo "Available recipes:"
	@sed -n 's/^##/    /p' $< | column -t -s '='
