# Go Jdenticon Makefile
# Provides convenient commands for building, testing, and profiling

.PHONY: help build test bench clean memory-test memory-profile load-test analyze-memory

# Default target
help:
	@echo "Go Jdenticon - Available Commands:"
	@echo ""
	@echo "Building:"
	@echo "  make build              Build all binaries (CLI + tools)"
	@echo "  make jdenticon-cli      Build CLI only" 
	@echo "  make version-info       Show version information"
	@echo "  make clean              Clean build artifacts"
	@echo ""
	@echo "Testing:"
	@echo "  make test               Run all tests"
	@echo "  make test-race          Run tests with race detection"
	@echo "  make test-coverage      Run tests with coverage report"
	@echo "  make bench              Run all benchmarks"
	@echo ""
	@echo "Memory Leak Validation (Task 26):"
	@echo "  make memory-test        Run memory leak validation tests"
	@echo "  make memory-bench       Run memory leak benchmarks with profiling"
	@echo "  make load-test          Run sustained load test (5 minutes)"
	@echo "  make load-test-long     Run extended load test (30 minutes)"
	@echo "  make memory-profile     Interactive memory profiling session"
	@echo "  make analyze-memory     Analyze latest memory profiles"
	@echo ""
	@echo "Advanced Profiling:"
	@echo "  make profile-heap       Generate heap profile"
	@echo "  make profile-cpu        Generate CPU profile" 
	@echo "  make profile-web        Start web UI for profile analysis"
	@echo "  make profile-continuous Run continuous profiling for 1 hour"
	@echo ""
	@echo "Examples:"
	@echo "  make memory-test        # Quick memory leak validation"
	@echo "  make load-test          # 5-minute sustained load test"
	@echo "  make profile-web        # Web UI for profile analysis"

# Go parameters
GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOGET=$(GOCMD) get
GOMOD=$(GOCMD) mod

# Version information
VERSION ?= $(shell git describe --tags --exact-match 2>/dev/null || git describe --tags 2>/dev/null || echo "dev")
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
BUILD_DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")

# Build flags for version injection
LDFLAGS=-ldflags "-X gitea.dockr.co/kev/go-jdenticon/cmd/jdenticon.Version=$(VERSION) \
                  -X gitea.dockr.co/kev/go-jdenticon/cmd/jdenticon.Commit=$(COMMIT) \
                  -X gitea.dockr.co/kev/go-jdenticon/cmd/jdenticon.BuildDate=$(BUILD_DATE)"

# Build targets
CLI_BINARY=jdenticon-cli
LOAD_TEST_BINARY=cmd/memory-load-test/memory-load-test

# Build all binaries
build: $(CLI_BINARY) $(LOAD_TEST_BINARY)
	@echo "Building Go Jdenticon..."
	$(GOBUILD) -v ./...

$(CLI_BINARY):
	@echo "Building jdenticon CLI with version $(VERSION)..."
	$(GOBUILD) $(LDFLAGS) -o $(CLI_BINARY) ./cmd/jdenticon

$(LOAD_TEST_BINARY):
	@echo "Building memory load test binary..."
	$(GOBUILD) -o $(LOAD_TEST_BINARY) ./cmd/memory-load-test

# Show version information that will be injected
version-info:
	@echo "Version Information:"
	@echo "  Version:    $(VERSION)"
	@echo "  Commit:     $(COMMIT)"
	@echo "  Build Date: $(BUILD_DATE)"

# Build specifically with version information (alias for jdenticon-cli)
jdenticon: $(CLI_BINARY)

# Clean build artifacts
clean:
	@echo "Cleaning build artifacts..."
	$(GOCLEAN)
	rm -f $(CLI_BINARY)
	rm -f $(LOAD_TEST_BINARY)
	rm -f *.prof
	rm -f cpu.prof mem.prof heap.prof

clean-profiles:
	@echo "Cleaning all profile data..."
	rm -rf profiles/

# Testing
test:
	@echo "Running all tests..."
	$(GOTEST) -v ./...

test-race:
	@echo "Running tests with race detection..."
	$(GOTEST) -race -v ./...

test-coverage:
	@echo "Running tests with coverage..."
	$(GOTEST) -coverprofile=coverage.out -v ./...
	$(GOCMD) tool cover -html=coverage.out -o coverage.html
	@echo "Coverage report: coverage.html"

bench:
	@echo "Running all benchmarks..."
	$(GOTEST) -bench=. -benchmem ./...

# Memory leak validation (Task 26)
memory-test:
	@echo "Running memory leak validation tests..."
	$(GOTEST) -v -run TestMemoryLeak ./jdenticon

memory-bench:
	@echo "Running memory leak benchmarks with profiling..."
	mkdir -p profiles
	$(eval TIMESTAMP := $(shell date +%Y%m%d_%H%M%S))
	$(eval MEM_PROF := profiles/memory-bench-$(TIMESTAMP).prof)
	$(eval CPU_PROF := profiles/cpu-bench-$(TIMESTAMP).prof)
	$(GOTEST) -bench=BenchmarkMemoryLeak \
		-benchtime=5m \
		-memprofile=$(MEM_PROF) \
		-memprofilerate=1 \
		-cpuprofile=$(CPU_PROF) \
		-benchmem \
		./jdenticon
	@echo "Profiles saved in profiles/ directory"
	@ln -sf $(shell basename $(MEM_PROF)) profiles/mem-latest.prof
	@ln -sf $(shell basename $(CPU_PROF)) profiles/cpu-latest.prof
	@echo "Created symlinks for latest profiles (mem-latest.prof, cpu-latest.prof)"

load-test: $(LOAD_TEST_BINARY)
	@echo "Running 5-minute sustained load test..."
	./$(LOAD_TEST_BINARY) -duration=5m -workers=4 -cache-size=1000

load-test-long: $(LOAD_TEST_BINARY)
	@echo "Running 30-minute extended load test..."
	./$(LOAD_TEST_BINARY) -duration=30m -workers=8 -cache-size=500

memory-profile:
	@echo "Starting interactive memory profiling session..."
	./scripts/memory-profile.sh benchmark --duration=10m

analyze-memory:
	@echo "Analyzing latest memory profiles..."
	@if [ -f profiles/mem-latest.prof ]; then \
		echo "Opening memory profile analysis..."; \
		$(GOCMD) tool pprof profiles/mem-latest.prof; \
	else \
		echo "No memory profile found. Run 'make memory-bench' first."; \
	fi

# Advanced profiling commands
profile-heap:
	@echo "Generating heap profile (30 seconds)..."
	mkdir -p profiles
	$(GOTEST) -bench=BenchmarkMemoryLeakSustainedLoad \
		-benchtime=30s \
		-memprofile=profiles/heap-$$(date +%Y%m%d_%H%M%S).prof \
		-memprofilerate=1 \
		./jdenticon

profile-cpu:
	@echo "Generating CPU profile (30 seconds)..."
	mkdir -p profiles
	$(GOTEST) -bench=BenchmarkMemoryLeakSustainedLoad \
		-benchtime=30s \
		-cpuprofile=profiles/cpu-$$(date +%Y%m%d_%H%M%S).prof \
		./jdenticon

profile-web:
	@echo "Starting web UI for profile analysis..."
	@if [ -f profiles/mem-latest.prof ]; then \
		echo "Opening http://localhost:8080 for profile analysis..."; \
		$(GOCMD) tool pprof -http=:8080 profiles/mem-latest.prof; \
	else \
		echo "No memory profile found. Run 'make memory-bench' first."; \
	fi

profile-continuous: $(LOAD_TEST_BINARY)
	@echo "Running continuous profiling for 1 hour..."
	./scripts/memory-profile.sh continuous --duration=1h --workers=6

# Development helpers
deps:
	@echo "Downloading dependencies..."
	$(GOMOD) download
	$(GOMOD) tidy

verify:
	@echo "Verifying dependencies..."
	$(GOMOD) verify

fmt:
	@echo "Formatting code..."
	$(GOCMD) fmt ./...

vet:
	@echo "Running go vet..."
	$(GOCMD) vet ./...

lint:
	@echo "Running golangci-lint..."
	@if command -v golangci-lint >/dev/null 2>&1; then \
		golangci-lint run; \
	else \
		echo "golangci-lint not installed. Install with: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest"; \
	fi

# Task 26 validation workflow
task-26: memory-test memory-bench load-test
	@echo ""
	@echo "=== Task 26: Memory Leak Validation Complete ==="
	@echo "✅ Memory leak tests passed"
	@echo "✅ Memory benchmarks completed with profiling"
	@echo "✅ Sustained load test completed"
	@echo ""
	@echo "Next steps:"
	@echo "  make analyze-memory     # Analyze memory profiles"
	@echo "  make profile-web        # Web UI for detailed analysis"
	@echo "  make load-test-long     # Extended validation (30 min)"
	@echo ""
	@if [ -d profiles ]; then \
		echo "Profile files available in profiles/ directory:"; \
		ls -la profiles/; \
	fi

# Quick validation for CI
ci-memory-check:
	@echo "Quick memory validation for CI..."
	$(GOTEST) -timeout=10m -run TestMemoryLeak ./jdenticon
	$(GOTEST) -bench=BenchmarkMemoryLeakSustainedLoad -benchtime=1m ./jdenticon