# =============================================================================
# TOP-LEVEL BUILD OVERVIEW
# =============================================================================
# This file keeps the high-level project view:
# - shared paths
# - application metadata / versioning
# - binary build targets
# - test targets
#
# Proto / gRPC generation logic lives in mk/proto.mk to keep this file readable.
# =============================================================================

SRC_DIR := src
GENERATED_DIR := $(SRC_DIR)/generated

include mk/proto.mk

# ============================================================================
# APPLICATION METADATA (Single Source of Truth)
# ============================================================================
APP_NAME := Stage API Go Client
APP_BINARY := stage-api-go-client

# ============================================================================
# SEMANTIC VERSIONING (MAJOR.MINOR.PATCH)
# ============================================================================
## VERSION FORMAT: major.minor.patch+build_number-commit_hash
# VERSION_MAJOR: Major version - manually incremented for breaking changes
# VERSION_MINOR: Minor version - manually incremented for new features
# PATCH: Patch version - manually incremented for bugfixes
# BUILD_NUMBER: Build number - passed from outside (CI, etc.)
# Usage:
#   make build                              # Uses 1.1.0+unknown-unknown
#   make build PATCH=5 BUILD_NUMBER=42      # Uses 1.1.5+42-abcdefg
#   make build VERSION_FILE=version.txt      # Writes version string to version.txt
#   Edit Makefile manually to change MAJOR/MINOR/PATCH
# ============================================================================
VERSION_MAJOR ?= 1
VERSION_MINOR ?= 1
PATCH ?= 0
BUILD_NUMBER ?= localbuild
COMMIT_HASH := $(shell git rev-parse --short=7 HEAD 2>/dev/null || echo "unknown")
EXTRA_VERSION := $(BUILD_NUMBER)-$(COMMIT_HASH)
VERSION := $(VERSION_MAJOR).$(VERSION_MINOR).$(PATCH)+$(EXTRA_VERSION)

# Build metadata
BUILD_DATE := $(shell date -u +'%Y-%m-%d %H:%M:%S UTC')
GO_VERSION := $(shell go version | awk '{print $$3}')

LDFLAGS := -ldflags "-s -w -X 'main.AppName=$(APP_NAME)' -X main.Version=$(VERSION) -X 'main.BuildDate=$(BUILD_DATE)' -X main.CommitHash=$(COMMIT_HASH) -X main.GoVersion=$(GO_VERSION)"

all:


.PHONY: all clean build build-linux build-windows build-darwin build-darwin-arm64 build-darwin-universal build-macos \
        build-proto verify-proto-source \
        test-unit test-unit-verbose test-unit-junit \
        test-integration test-integration-junit \
		test-all test-junit

clean:
	rm -f bin/linux/stage-api-go-client
	rm -f bin/windows/stage-api-go-client.exe
	rm -f bin/darwin/stage-api-go-client
	rm -f bin/darwin/stage-api-go-client-arm64
	rm -f bin/darwin/stage-api-go-client-universal
	rm -rf test-results/
	rm -f $(PROTO_SENTINEL)
	rm -f $(PROTO_VERSION_SENTINELS)
	rm -rf $(GENERATED_DIR)

# Auto-detect OS and build for the current platform
build:
	@if [ "$(OS)" = "Windows_NT" ]; then \
		$(MAKE) build-windows; \
	elif [ "$$(uname -s)" = "Darwin" ]; then \
		if command -v lipo >/dev/null 2>&1; then \
			$(MAKE) build-macos; \
		else \
			$(MAKE) build-darwin; \
		fi; \
	else \
		$(MAKE) build-linux; \
	fi

build-linux: $(PROTO_SENTINEL)
	@echo "Building for Linux (amd64)..."
	@echo "  Version: $(VERSION_MAJOR).$(VERSION_MINOR).$(PATCH) (use PATCH=X to override)"
	@echo "  Build Date: $(BUILD_DATE)"
	@echo "  Commit: $(COMMIT_HASH)"
	CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o bin/linux/stage-api-go-client ./src
	$(if $(VERSION_FILE),echo $(VERSION) > $(VERSION_FILE); echo "Version $(VERSION) written to $(VERSION_FILE)",)

build-windows: $(PROTO_SENTINEL)
	@echo "Building for Windows (amd64)..."
	@echo "  Version: $(VERSION_MAJOR).$(VERSION_MINOR).$(PATCH) (use PATCH=X to override)"
	@echo "  Build Date: $(BUILD_DATE)"
	@echo "  Commit: $(COMMIT_HASH)"
	GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o bin/windows/stage-api-go-client.exe ./src
	$(if $(VERSION_FILE),echo $(VERSION) > $(VERSION_FILE); echo "Version $(VERSION) written to $(VERSION_FILE)",)

build-darwin: $(PROTO_SENTINEL)
	@echo "Building for macOS (amd64)..."
	@echo "  Version: $(VERSION_MAJOR).$(VERSION_MINOR).$(PATCH) (use PATCH=X to override)"
	@echo "  Build Date: $(BUILD_DATE)"
	@echo "  Commit: $(COMMIT_HASH)"
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o bin/darwin/stage-api-go-client ./src
	$(if $(VERSION_FILE),echo $(VERSION) > $(VERSION_FILE); echo "Version $(VERSION) written to $(VERSION_FILE)",)

build-darwin-arm64: $(PROTO_SENTINEL)
	@echo "Building for macOS (arm64)..."
	@echo "  Version: $(VERSION_MAJOR).$(VERSION_MINOR).$(PATCH) (use PATCH=X to override)"
	@echo "  Build Date: $(BUILD_DATE)"
	@echo "  Commit: $(COMMIT_HASH)"
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o bin/darwin/stage-api-go-client-arm64 ./src
	$(if $(VERSION_FILE),echo $(VERSION) > $(VERSION_FILE); echo "Version $(VERSION) written to $(VERSION_FILE)",)

build-darwin-universal: build-darwin build-darwin-arm64
	@command -v lipo >/dev/null 2>&1 || { echo "lipo not found. Run this target on macOS (or install llvm-lipo/cctools lipo)."; exit 1; }
	@lipo -create -output bin/darwin/stage-api-go-client-universal \
		bin/darwin/stage-api-go-client \
		bin/darwin/stage-api-go-client-arm64
	@echo "Built universal macOS binary: bin/darwin/stage-api-go-client-universal"

build-macos: build-darwin-universal
	@echo "macOS binaries built: bin/darwin/stage-api-go-client, bin/darwin/stage-api-go-client-arm64, and bin/darwin/stage-api-go-client-universal"

# ============================================================================
# TESTING TARGETS
# ============================================================================

# Unit Tests (primary targets)
test-unit:
	@echo "Running unit tests..."
	@go test ./src/cli ./src/handler ./src/handler/v1/... ./src/ui/...

test-unit-verbose:
	@echo "Running unit tests (verbose)..."
	@go test -v ./src/cli ./src/handler ./src/handler/v1/... ./src/ui/...

# Integration Tests
test-integration:
	@echo "Running integration tests..."
	@if [ ! -f "bin/linux/stage-api-go-client" ]; then \
		echo "Binary not found. Building..."; \
		$(MAKE) build; \
	fi
	@bash scripts/integration-test.sh

# JUnit Output for CI/CD (Bamboo, Jenkins, etc.)
test-unit-junit:
	@echo "Running unit tests with JUnit output..."
	@mkdir -p test-results
	@go test -v -json ./src/cli ./src/handler ./src/handler/v1/... ./src/ui/... 2>&1 | go run github.com/jstemmer/go-junit-report/v2@latest -set-exit-code > test-results/junit-unit-tests.xml || true
	@echo "JUnit report generated: test-results/junit-unit-tests.xml"

test-integration-junit:
	@echo "Running integration tests with JUnit output..."
	@mkdir -p test-results
	@if [ ! -f "bin/linux/stage-api-go-client" ]; then \
		echo "Binary not found. Building..."; \
		$(MAKE) build; \
	fi
	@bash scripts/integration-test-junit.sh > test-results/junit-integration-tests.xml
	@echo "Integration JUnit report generated: test-results/junit-integration-tests.xml"

# Primary JUnit target for CI/CD pipelines
test-junit: test-unit-junit test-integration-junit
	@echo "All JUnit test reports generated in test-results/"

# All Tests
# Note: For CI/CD systems that need JUnit XML output, use 'make test-junit' instead,
# which will generate both unit and integration test reports in test-results/ directory
test-all: test-unit test-integration
	@echo "All tests completed!"


