# Makefile pour Veza Backend API
# Ce Makefile facilite le développement et la maintenance du backend Go

.PHONY: help build test clean lint format vet tidy deps install run dev docker-build docker-run

# Variables
BINARY_NAME=veza-backend-api
DOCKER_IMAGE=veza-backend-api
DOCKER_TAG=latest
GO_VERSION=1.21
LINT_VERSION=1.54.2

# Couleurs pour les messages
GREEN=\033[0;32m
YELLOW=\033[1;33m
RED=\033[0;31m
NC=\033[0m # No Color

# Aide par défaut
help: ## Affiche cette aide
	@echo "$(GREEN)Veza Backend API - Makefile$(NC)"
	@echo ""
	@echo "$(YELLOW)Commandes disponibles:$(NC)"
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "  $(GREEN)%-15s$(NC) %s\n", $$1, $$2}' $(MAKEFILE_LIST)

# Développement
build: ## Compile l'application
	@echo "$(GREEN)🔨 Compilation de l'application...$(NC)"
	@go build -o bin/$(BINARY_NAME) ./cmd/modern-server/main.go
	@echo "$(GREEN)✅ Compilation terminée: bin/$(BINARY_NAME)$(NC)"

build-linux: ## Compile l'application pour Linux
	@echo "$(GREEN)🔨 Compilation pour Linux...$(NC)"
	@GOOS=linux GOARCH=amd64 go build -o bin/$(BINARY_NAME)-linux ./cmd/modern-server/main.go
	@echo "$(GREEN)✅ Compilation Linux terminée: bin/$(BINARY_NAME)-linux$(NC)"

# Tests
test: ## Exécute tous les tests (sans tests en quarantaine)
	@echo "$(GREEN)🧪 Exécution des tests...$(NC)"
	@go test -v ./internal/... -short -tags '!integration'

test-coverage: ## Exécute les tests avec couverture
	@echo "$(GREEN)🧪 Tests avec couverture...$(NC)"
	@go test -coverprofile=coverage.out ./internal/... -short -tags '!integration'
	@go tool cover -html=coverage.out -o coverage.html
	@echo "$(GREEN)✅ Rapport de couverture généré: coverage.html$(NC)"

test-race: ## Exécute les tests avec détection de race conditions
	@echo "$(GREEN)🧪 Tests avec détection de race conditions...$(NC)"
	@go test -race ./internal/... -short -tags '!integration'

test-integration: ## Exécute les tests d'intégration (avec tests en quarantaine)
	@echo "$(GREEN)🧪 Exécution des tests d'intégration...$(NC)"
	@echo "$(YELLOW)Note: Nécessite Docker pour testcontainers (PostgreSQL + Redis)$(NC)"
	@go test -tags=integration -v ./tests/integration/...

test-quarantine: ## Exécute les tests en quarantaine (validation manuelle)
	@echo "$(GREEN)🧪 Exécution des tests en quarantaine...$(NC)"
	@echo "$(YELLOW)Note: Nécessite Docker pour testcontainers$(NC)"
	@go test ./internal/... -count=1 -tags integration -v

test-short: ## Exécute les tests courts uniquement
	@echo "$(GREEN)🧪 Tests courts...$(NC)"
	@go test ./internal/... -count=1 -short -tags '!integration' -timeout 30s

# Qualité du code
lint: ## Exécute golangci-lint
	@echo "$(GREEN)🔍 Vérification avec golangci-lint...$(NC)"
	@if command -v golangci-lint >/dev/null 2>&1; then \
		golangci-lint run; \
	else \
		echo "$(YELLOW)⚠️  golangci-lint non installé. Installation...$(NC)"; \
		go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$(LINT_VERSION); \
		golangci-lint run; \
	fi

format: ## Formate le code Go
	@echo "$(GREEN)🎨 Formatage du code...$(NC)"
	@go fmt ./...
	@if command -v goimports >/dev/null 2>&1; then \
		find . -name "*.go" -not -path "./vendor/*" | xargs goimports -w; \
	else \
		echo "$(YELLOW)⚠️  goimports non installé. Installation...$(NC)"; \
		go install golang.org/x/tools/cmd/goimports@latest; \
		find . -name "*.go" -not -path "./vendor/*" | xargs goimports -w; \
	fi
	@echo "$(GREEN)✅ Code formaté$(NC)"

vet: ## Exécute go vet
	@echo "$(GREEN)🔍 Vérification avec go vet...$(NC)"
	@go vet ./...

# Dépendances
deps: ## Installe les dépendances
	@echo "$(GREEN)📦 Installation des dépendances...$(NC)"
	@go mod download
	@go mod tidy
	@echo "$(GREEN)✅ Dépendances installées$(NC)"

install: ## Installe l'application
	@echo "$(GREEN)📦 Installation de l'application...$(NC)"
	@go install ./cmd/modern-server/main.go
	@echo "$(GREEN)✅ Application installée$(NC)"

# Nettoyage
clean: ## Nettoie les fichiers générés
	@echo "$(GREEN)🧹 Nettoyage...$(NC)"
	@rm -rf bin/
	@rm -f coverage.out coverage.html
	@go clean
	@echo "$(GREEN)✅ Nettoyage terminé$(NC)"

# Exécution
run: build ## Compile et exécute l'application
	@echo "$(GREEN)🚀 Démarrage de l'application...$(NC)"
	@./bin/$(BINARY_NAME)

dev: ## Exécute l'application en mode développement
	@echo "$(GREEN)🚀 Mode développement...$(NC)"
	@go run ./cmd/modern-server/main.go

# Docker
docker-build: ## Construit l'image Docker
	@echo "$(GREEN)🐳 Construction de l'image Docker...$(NC)"
	@docker build -t $(DOCKER_IMAGE):$(DOCKER_TAG) .
	@echo "$(GREEN)✅ Image Docker construite: $(DOCKER_IMAGE):$(DOCKER_TAG)$(NC)"

docker-run: docker-build ## Construit et exécute l'image Docker
	@echo "$(GREEN)🐳 Exécution de l'image Docker...$(NC)"
	@docker run -p 8080:8080 $(DOCKER_IMAGE):$(DOCKER_TAG)

# Outils de développement
install-tools: ## Installe les outils de développement
	@echo "$(GREEN)🛠️  Installation des outils de développement...$(NC)"
	@go install golang.org/x/tools/cmd/goimports@latest
	@go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$(LINT_VERSION)
	@go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest
	@go install golang.org/x/vuln/cmd/govulncheck@latest
	@go install honnef.co/go/tools/cmd/staticcheck@latest
	@echo "$(GREEN)✅ Outils installés$(NC)"

# Sécurité
security: ## Exécute les vérifications de sécurité
	@echo "$(GREEN)🔒 Vérifications de sécurité...$(NC)"
	@if command -v gosec >/dev/null 2>&1; then \
		gosec ./...; \
	else \
		echo "$(YELLOW)⚠️  gosec non installé. Installation...$(NC)"; \
		go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest; \
		gosec ./...; \
	fi
	@echo "$(GREEN)🔒 Recherche de vulnérabilités (govulncheck)...$(NC)"
	@if command -v govulncheck >/dev/null 2>&1; then \
		govulncheck ./...; \
	else \
		echo "$(YELLOW)⚠️  govulncheck non installé. Installation...$(NC)"; \
		go install golang.org/x/vuln/cmd/govulncheck@latest; \
		$$(go env GOPATH)/bin/govulncheck ./... || \
		$$HOME/go/bin/govulncheck ./... || \
		(echo "$(RED)❌ Impossible de trouver govulncheck après installation$(NC)" && exit 1); \
	fi

vulncheck: ## Scan des vulnérabilités Go uniquement (govulncheck)
	@echo "$(GREEN)🔒 Scan des vulnérabilités Go...$(NC)"
	@if command -v govulncheck >/dev/null 2>&1; then \
		govulncheck ./...; \
	else \
		echo "$(YELLOW)⚠️  govulncheck non installé. Installation...$(NC)"; \
		go install golang.org/x/vuln/cmd/govulncheck@latest; \
		$$(go env GOPATH)/bin/govulncheck ./... || \
		$$HOME/go/bin/govulncheck ./... || \
		(echo "$(RED)❌ Impossible de trouver govulncheck après installation$(NC)" && exit 1); \
	fi

docker-scan: docker-build ## Scan de l'image Docker avec Trivy
	@echo "$(GREEN)🔒 Scan de l'image Docker...$(NC)"
	@if command -v trivy >/dev/null 2>&1; then \
		trivy image --severity CRITICAL,HIGH $(DOCKER_IMAGE):$(DOCKER_TAG); \
	else \
		echo "$(YELLOW)⚠️  Trivy non installé. Utilisation via Docker...$(NC)"; \
		docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
			aquasec/trivy:latest image --severity CRITICAL,HIGH $(DOCKER_IMAGE):$(DOCKER_TAG); \
	fi

docker-scan-full: docker-build ## Scan complet de l'image Docker (toutes sévérités)
	@echo "$(GREEN)🔒 Scan complet de l'image Docker...$(NC)"
	@if command -v trivy >/dev/null 2>&1; then \
		trivy image $(DOCKER_IMAGE):$(DOCKER_TAG); \
	else \
		echo "$(YELLOW)⚠️  Trivy non installé. Utilisation via Docker...$(NC)"; \
		docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
			aquasec/trivy:latest image $(DOCKER_IMAGE):$(DOCKER_TAG); \
	fi

# Performance
load-test: ## Exécute le test de charge k6
	@echo "$(GREEN)🔥 Exécution du test de charge (Uploads)...$(NC)"
	@docker run --rm -i --network=host grafana/k6 run - < scripts/load_test_uploads.js

benchmark: ## Exécute les benchmarks
	@echo "$(GREEN)⚡ Exécution des benchmarks...$(NC)"
	@go test -bench=. ./...

# Documentation
docs: ## Génère la documentation
	@echo "$(GREEN)📚 Génération de la documentation...$(NC)"
	@go doc -all ./... > docs.txt
	@echo "$(GREEN)✅ Documentation générée: docs.txt$(NC)"

# Scripts personnalisés
cleanup: ## Exécute le script de nettoyage
	@echo "$(GREEN)🧹 Exécution du script de nettoyage...$(NC)"
	@./scripts/cleanup-go.sh

# CI/CD
ci: deps lint security test build ## Pipeline CI complet
	@echo "$(GREEN)✅ Pipeline CI terminé$(NC)"

ci-test: ## CI: Tests normaux (sans quarantaine)
	@echo "$(GREEN)🧪 CI: Tests normaux...$(NC)"
	@go test ./internal/... -count=1 -short -tags '!integration' -coverprofile=coverage.out

ci-test-integration: ## CI: Tests d'intégration (séparé, optionnel)
	@echo "$(GREEN)🧪 CI: Tests d'intégration...$(NC)"
	@go test ./tests/integration/... -tags integration -v -timeout 10m

# Déploiement
deploy-staging: build-linux ## Déploie en staging
	@echo "$(GREEN)🚀 Déploiement en staging...$(NC)"
	@echo "$(YELLOW)⚠️  Déploiement en staging non implémenté$(NC)"

deploy-production: build-linux ## Déploie en production
	@echo "$(GREEN)🚀 Déploiement en production...$(NC)"
	@echo "$(YELLOW)⚠️  Déploiement en production non implémenté$(NC)"

# Monitoring
health: ## Vérifie la santé de l'application
	@echo "$(GREEN)🏥 Vérification de la santé...$(NC)"
	@curl -f http://localhost:8080/health || echo "$(RED)❌ Application non accessible$(NC)"

# Base de données
migrate: ## Exécute les migrations de base de données
	@echo "$(GREEN)🗄️  Exécution des migrations...$(NC)"
	@go run cmd/migrate_tool/main.go
	@echo "$(GREEN)✅ Migrations terminées$(NC)"

db-migrate: migrate ## Alias pour migrate

db-seed: ## Peuple la base de données avec des données de test
	@echo "$(GREEN)🌱 Peuplement de la base de données...$(NC)"
	@echo "$(YELLOW)⚠️  Seeding non implémenté$(NC)"

# Lab Environment
migrate-lab: ## Applique les migrations en environnement Lab
	@echo "$(GREEN)🧪 Migrating Lab Database...$(NC)"
	@./scripts/apply_migrations_lab.sh

run-lab: build ## Lance l'application en mode Lab (dégradé sans Redis/RabbitMQ bloquant)
	@echo "$(GREEN)🧪 Running Lab Server...$(NC)"
	@export DATABASE_URL=$${VEZA_LAB_DSN:-postgres://veza:veza_password@localhost:5432/veza_lab?sslmode=disable} && \
	export APP_ENV=development && \
	export JWT_SECRET=lab-insecure-secret-key-must-be-32-chars-long && \
	export REDIS_URL=redis://localhost:6379/0 && \
	export REDIS_ENABLE=false && \
	export RABBITMQ_ENABLE=false && \
	./bin/$(BINARY_NAME)

# Par défaut
.DEFAULT_GOAL := help
