# ==============================================================================
# VEZA MONOREPO - ULTIMATE CONTROL PLANE
# ==============================================================================
# Stack:  Hybrid (Docker Infra + Bare Metal Apps)
# System: Linux / Bash
# ==============================================================================

# --- Auto-Configuration ---
-include .env

# Shell setup
SHELL := /bin/bash
.ONESHELL:
.DEFAULT_GOAL := help

# --- Variables ---
# Ports
export PORT_GO     ?= 8080
export PORT_CHAT   ?= 3000
export PORT_STREAM ?= 3001
export PORT_WEB    ?= 5173

# Database & Infra
export DB_USER ?= veza
export DB_PASS ?= password
export DB_NAME ?= veza
export DB_HOST ?= localhost
export DB_PORT ?= 5432

# Connection Strings
export DATABASE_URL = postgres://$(DB_USER):$(DB_PASS)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=disable
export REDIS_URL    = redis://localhost:6379
export AMQP_URL     = amqp://$(DB_USER):$(DB_PASS)@localhost:5672

# Directories
DIR_GO     := veza-backend-api
DIR_CHAT   := veza-chat-server
DIR_STREAM := veza-stream-server
DIR_WEB    := apps/web

# --- Aesthetics & UI ---
# Using echo -e compatible variables
BOLD   := [1m
RED    := [0;31m
GREEN  := [0;32m
YELLOW := [0;33m
BLUE   := [0;34m
PURPLE := [0;35m
CYAN   := [0;36m
NC     := [0m

# Helper for consistent echoing
ECHO_CMD = echo -e

# ==============================================================================
# 1. HELP & DASHBOARD
# ==============================================================================
.PHONY: help
help: ## Show this dashboard
	@$(ECHO_CMD) ""
	@$(ECHO_CMD) "${BOLD}${PURPLE}⚡ VEZA MONOREPO CLI ⚡${NC}"
	@$(ECHO_CMD) "----------------------------------------------------------------"
	@$(ECHO_CMD) "${BOLD}INFRASTRUCTURE:${NC}"
	@printf "  ${CYAN}%-15s${NC} %s\n" "Postgres" "${DATABASE_URL}"
	@printf "  ${CYAN}%-15s${NC} %s\n" "Redis" "${REDIS_URL}"
	@printf "  ${CYAN}%-15s${NC} %s\n" "RabbitMQ" "UI: http://localhost:15672 (veza/password)"
	@$(ECHO_CMD) ""
	@$(ECHO_CMD) "${BOLD}AVAILABLE COMMANDS:${NC}"
	@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "  ${YELLOW}%-20s${NC} %s\n", $$1, $$2}'
	@$(ECHO_CMD) ""

# ==============================================================================
# 2. SETUP & TOOLS
# ============================================================================== 
.PHONY: setup install-deps install-tools check-tools

setup: check-tools install-tools install-deps ## Full project initialization
	@$(ECHO_CMD) "${BOLD}${GREEN}✅ Setup Complete! Ready to rock with 'make dev'.${NC}"

check-tools:
	@$(ECHO_CMD) "${BLUE}Checking core requirements...${NC}"
	@for tool in docker go cargo npm; do \
		command -v $$tool >/dev/null 2>&1 || { $(ECHO_CMD) "${RED}❌ $$tool is missing!${NC}"; exit 1; }; \
	done

install-deps: ## Install code dependencies
	@$(ECHO_CMD) "${BLUE}📦 Installing dependencies...${NC}"
	@$(ECHO_CMD) "   -> [Go] Downloading modules..."
	@(cd $(DIR_GO) && go mod download)
	@$(ECHO_CMD) "   -> [Rust Chat] Fetching crates..."
	@(cd $(DIR_CHAT) && cargo fetch)
	@$(ECHO_CMD) "   -> [Rust Stream] Fetching crates..."
	@(cd $(DIR_STREAM) && cargo fetch)
	@$(ECHO_CMD) "   -> [Web] Installing npm packages..."
	@(cd $(DIR_WEB) && npm install --silent)

install-tools: ## Install Power User tools (Hot Reload, Linters)
	@$(ECHO_CMD) "${BLUE}🛠️  Installing Dev Tools (Hot Reload & Linters)...${NC}"
	@$(ECHO_CMD) "   -> Checking air (Go Hot Reload)..."
	@command -v air >/dev/null 2>&1 || go install github.com/air-verse/air@latest
	@$(ECHO_CMD) "   -> Checking cargo-watch (Rust Hot Reload)..."
	@command -v cargo-watch >/dev/null 2>&1 || cargo install cargo-watch
	@$(ECHO_CMD) "   -> Checking sqlx-cli..."
	@command -v sqlx >/dev/null 2>&1 || cargo install sqlx-cli --no-default-features --features native-tls,postgres
	@$(ECHO_CMD) "${GREEN}✅ Tools check done.${NC}"

# ==============================================================================
# 3. INFRASTRUCTURE & DB
# ============================================================================== 
.PHONY: infra-up infra-down db-shell redis-shell db-migrate status

infra-up: ## Start Docker Infra (with health checks)
	@$(ECHO_CMD) "${BLUE}🐳 Starting Infrastructure...${NC}"
	@docker compose up -d
	@$(MAKE) -s wait-for-infra

infra-down: ## Stop Docker Infra
	@$(ECHO_CMD) "${BLUE}🛑 Stopping Infrastructure...${NC}"
	@docker compose down

wait-for-infra:
	@printf "${BLUE}⏳ Waiting for services...${NC}"
	@until docker compose exec -T postgres pg_isready -U $(DB_USER) > /dev/null 2>&1; do printf "."; sleep 1; done
	@until docker compose exec -T redis redis-cli ping > /dev/null 2>&1; do printf "."; sleep 1; done
	@$(ECHO_CMD) " ${GREEN}OK${NC}"

db-shell: ## Connect to Postgres shell
	@docker compose exec postgres psql -U $(DB_USER) -d $(DB_NAME)

redis-shell: ## Connect to Redis shell
	@docker compose exec redis redis-cli

db-migrate: infra-up ## Run all database migrations
	@$(ECHO_CMD) "${BLUE}🔄 Running Migrations...${NC}"
	# Go Backend (Custom tool)
	@$(ECHO_CMD) "   -> [Go] Migrating..."
	@(cd $(DIR_GO) && go run cmd/migrate_tool/main.go up || $(ECHO_CMD) "${YELLOW}Warning: Go migration failed or tool missing${NC}")
	# Rust Services (SQLx)
	@$(ECHO_CMD) "   -> [Chat] Migrating..."
	@(cd $(DIR_CHAT) && sqlx migrate run || $(ECHO_CMD) "${YELLOW}Warning: Chat migration failed (sqlx installed?)${NC}")
	@$(ECHO_CMD) "   -> [Stream] Migrating..."
	@(cd $(DIR_STREAM) && sqlx migrate run || $(ECHO_CMD) "${YELLOW}Warning: Stream migration failed${NC}")
	@$(ECHO_CMD) "${GREEN}✅ Migrations done.${NC}"

status: ## Show system health & stats
	@$(ECHO_CMD) "${BOLD}DOCKER STATS:${NC}"
	@docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
	@$(ECHO_CMD) ""
	@$(ECHO_CMD) "${BOLD}LOCAL PORTS:${NC}"
	@lsof -i :$(PORT_GO) -i :$(PORT_CHAT) -i :$(PORT_STREAM) -i :$(PORT_WEB) | grep LISTEN || echo "No apps listening."

# ==============================================================================
# 4. DEVELOPMENT (SMART MODE)
# ============================================================================== 
.PHONY: dev dev-backend check-ports

check-ports:
	@$(ECHO_CMD) "${BLUE}🔍 Checking ports...${NC}"
	@if lsof -i :$(PORT_GO) -t >/dev/null; then $(ECHO_CMD) "${RED}❌ Port $(PORT_GO) is busy!${NC}"; exit 1; fi
	@if lsof -i :$(PORT_CHAT) -t >/dev/null; then $(ECHO_CMD) "${RED}❌ Port $(PORT_CHAT) is busy!${NC}"; exit 1; fi
	@if lsof -i :$(PORT_STREAM) -t >/dev/null; then $(ECHO_CMD) "${RED}❌ Port $(PORT_STREAM) is busy!${NC}"; exit 1; fi

dev: check-ports infra-up ## Start Everything (Detects Hot Reload tools)
	@$(ECHO_CMD) "${BOLD}${PURPLE}🚀 STARTING HYBRID DEV ENVIRONMENT${NC}"
	@$(ECHO_CMD) "   Go:    http://localhost:${PORT_GO}"
	@$(ECHO_CMD) "   Chat:  http://localhost:${PORT_CHAT}"
	@$(ECHO_CMD) "   Web:   http://localhost:${PORT_WEB}"
	@$(ECHO_CMD) "${YELLOW}Hit Ctrl+C to stop all.${NC}"
	@(trap 'kill 0' SIGINT; \
		if command -v air >/dev/null; then \
			$(ECHO_CMD) "${GREEN}[Go] Hot Reload Active (Air)${NC}" && cd $(DIR_GO) && air & \
		else \
			$(ECHO_CMD) "${YELLOW}[Go] Standard Run${NC}" && cd $(DIR_GO) && go run cmd/api/main.go & \
		fi; \
		if command -v cargo-watch >/dev/null; then \
			$(ECHO_CMD) "${GREEN}[Chat] Hot Reload Active (Cargo Watch)${NC}" && cd $(DIR_CHAT) && cargo watch -x run -q & \
			$(ECHO_CMD) "${GREEN}[Stream] Hot Reload Active (Cargo Watch)${NC}" && cd $(DIR_STREAM) && cargo watch -x run -q & \
		else \
			$(ECHO_CMD) "${YELLOW}[Chat] Standard Run${NC}" && cd $(DIR_CHAT) && cargo run -q & \
			$(ECHO_CMD) "${YELLOW}[Stream] Standard Run${NC}" && cd $(DIR_STREAM) && cargo run -q & \
		fi; \
		$(ECHO_CMD) "${GREEN}[Web] Starting Vite...${NC}" && cd $(DIR_WEB) && npm run dev & \
		wait)

dev-backend: check-ports infra-up ## Start Backends Only (Hot Reload supported)
	@$(ECHO_CMD) "${BOLD}${PURPLE}🚀 STARTING BACKEND ONLY${NC}"
	@(trap 'kill 0' SIGINT; \
		if command -v air >/dev/null; then cd $(DIR_GO) && air & else cd $(DIR_GO) && go run cmd/api/main.go & fi; \
		if command -v cargo-watch >/dev/null; then cd $(DIR_CHAT) && cargo watch -x run -q & else cd $(DIR_CHAT) && cargo run -q & fi; \
		if command -v cargo-watch >/dev/null; then cd $(DIR_STREAM) && cargo watch -x run -q & else cd $(DIR_STREAM) && cargo run -q & fi; \
		wait)

# ==============================================================================
# 5. TEST & QUALITY
# ============================================================================== 
.PHONY: test lint fmt security clean-deep

test: infra-up ## Run All Tests (Fastest strategy)
	@$(ECHO_CMD) "${BLUE}🧪 Running Tests...${NC}"
	@$(ECHO_CMD) "   [Go] Unit Tests..."
	@(cd $(DIR_GO) && go test ./... -short)
	@$(ECHO_CMD) "   [Rust] Unit Tests..."
	@(cd $(DIR_CHAT) && cargo test --lib -q)
	@(cd $(DIR_STREAM) && cargo test --lib -q)
	@$(ECHO_CMD) "   [Web] Unit Tests..."
	@(cd $(DIR_WEB) && npm run test -- --run)
	@$(ECHO_CMD) "${GREEN}✅ All tests passed.${NC}"

lint: ## Lint everything
	@$(ECHO_CMD) "${BLUE}🔍 Linting Codebase...${NC}"
	@(cd $(DIR_CHAT) && cargo clippy -- -D warnings)
	@(cd $(DIR_STREAM) && cargo clippy -- -D warnings)
	@(cd $(DIR_GO) && golangci-lint run ./...)
	@(cd $(DIR_WEB) && npm run lint)

fmt: ## Format everything
	@$(ECHO_CMD) "${BLUE}✨ Formatting...${NC}"
	@(cd $(DIR_GO) && go fmt ./...)
	@(cd $(DIR_CHAT) && cargo fmt)
	@(cd $(DIR_STREAM) && cargo fmt)
	@(cd $(DIR_WEB) && npm run format)

clean-deep: infra-down ## ⚠️  Nuclear Clean (Confirm required)
	@read -p "Are you sure you want to delete ALL builds and volumes? [y/N] " ans && [ $${ans:-N} = y ]
	@$(ECHO_CMD) "${RED}☢️  DESTROYING ARTIFACTS...${NC}"
	@rm -rf $(DIR_WEB)/node_modules
	@rm -rf $(DIR_CHAT)/target $(DIR_STREAM)/target
	@docker compose down -v
	@$(ECHO_CMD) "${GREEN}System Cleaned.${NC}"
