# TankStopp Makefile
# Build and development management for TankStopp fuel tracking application

.PHONY: help build dev prod test clean format generate watch install deps migrate seed docker run

# Default target
.DEFAULT_GOAL := help

# Go parameters
GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOGET=$(GOCMD) get
GOMOD=$(GOCMD) mod
BINARY_NAME=tankstopp
BINARY_PATH=./$(BINARY_NAME)
MAIN_PATH=./cmd/main.go

# Configuration parameters
CONFIG_PATH=config.yaml
CONFIG_DEV_PATH=config.development.yaml
CONFIG_PROD_PATH=config.production.yaml

# Templ parameters
TEMPL_CMD=go tool templ
VIEWS_PATH=./internal/views

# Database parameters
DB_PATH=./fuel_stops.db
MIGRATIONS_PATH=./migrations

# Colors for output
RED=\033[0;31m
GREEN=\033[0;32m
YELLOW=\033[1;33m
BLUE=\033[0;34m
NC=\033[0m

help: ## Show this help message
	@echo "TankStopp Build System"
	@echo ""
	@echo "Usage: make [target]"
	@echo ""
	@echo "Targets:"
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
	@echo ""
	@echo "Configuration:"
	@echo "  Set CONFIG_ENV to 'development' or 'production' to use specific configs"
	@echo "  Example: make run CONFIG_ENV=development"

install: ## Install required tools and dependencies
	@echo "$(BLUE)[INFO]$(NC) Installing required tools..."
	@$(GOGET) -u github.com/a-h/templ/cmd/templ@latest
	@$(GOMOD) tidy
	@echo "$(GREEN)[SUCCESS]$(NC) Tools installed successfully"

deps: ## Download and tidy dependencies
	@echo "$(BLUE)[INFO]$(NC) Downloading dependencies..."
	@$(GOMOD) download
	@$(GOMOD) tidy
	@echo "$(GREEN)[SUCCESS]$(NC) Dependencies updated"

format: ## Format Go code and templ files
	@echo "$(BLUE)[INFO]$(NC) Formatting code..."
	@$(GOCMD) fmt ./...
	@if command -v $(TEMPL_CMD) > /dev/null 2>&1; then \
		$(TEMPL_CMD) fmt $(VIEWS_PATH)/; \
		echo "$(GREEN)[SUCCESS]$(NC) Code formatted successfully"; \
	else \
		echo "$(YELLOW)[WARNING]$(NC) templ not found, skipping templ formatting"; \
	fi

generate: ## Generate Go code from templ files
	@echo "$(BLUE)[INFO]$(NC) Generating Go code from templ files..."
	@if command -v $(TEMPL_CMD) > /dev/null 2>&1; then \
		$(TEMPL_CMD) generate $(VIEWS_PATH)/; \
		echo "$(GREEN)[SUCCESS]$(NC) Go code generated successfully"; \
	else \
		echo "$(RED)[ERROR]$(NC) templ not found. Run 'make install' first"; \
		exit 1; \
	fi

build: generate ## Build the application
	@echo "$(BLUE)[INFO]$(NC) Building application..."
	@$(GOBUILD) -o $(BINARY_NAME) $(MAIN_PATH)
	@echo "$(GREEN)[SUCCESS]$(NC) Application built successfully"

dev: ## Development build (format, generate, build)
	@echo "$(BLUE)[INFO]$(NC) Starting development build..."
	@$(MAKE) format
	@$(MAKE) generate
	@$(MAKE) build
	@echo "$(GREEN)[SUCCESS]$(NC) Development build completed"

prod: ## Production build (format, generate, test, build with optimizations)
	@echo "$(BLUE)[INFO]$(NC) Starting production build..."
	@$(MAKE) format
	@$(MAKE) generate
	@$(MAKE) test
	@$(GOBUILD) -ldflags="-s -w" -o $(BINARY_NAME) $(MAIN_PATH)
	@echo "$(GREEN)[SUCCESS]$(NC) Production build completed"

test: ## Run tests
	@echo "$(BLUE)[INFO]$(NC) Running tests..."
	@$(GOTEST) -v ./...
	@echo "$(GREEN)[SUCCESS]$(NC) All tests passed"

test-coverage: ## Run tests with coverage
	@echo "$(BLUE)[INFO]$(NC) Running tests with coverage..."
	@$(GOTEST) -v -coverprofile=coverage.out ./...
	@$(GOCMD) tool cover -html=coverage.out -o coverage.html
	@echo "$(GREEN)[SUCCESS]$(NC) Coverage report generated: coverage.html"

clean: ## Clean build artifacts and generated files
	@echo "$(BLUE)[INFO]$(NC) Cleaning build artifacts..."
	@$(GOCLEAN)
	@rm -f $(BINARY_NAME)
	@rm -f coverage.out coverage.html
	@find $(VIEWS_PATH) -name "*_templ.go" -delete
	@echo "$(GREEN)[SUCCESS]$(NC) Cleaned build artifacts"

run: build ## Build and run the application
	@echo "$(BLUE)[INFO]$(NC) Running application..."
	@$(BINARY_PATH)

run-hot: ## Run application in development mode with hot reload
	@echo "$(BLUE)[INFO]$(NC) Starting development server..."
	@if command -v air > /dev/null 2>&1; then \
		air; \
	else \
		echo "$(YELLOW)[WARNING]$(NC) air not found, running without hot reload"; \
		$(MAKE) run; \
	fi

watch: ## Watch for changes and rebuild (requires entr)
	@echo "$(BLUE)[INFO]$(NC) Starting watch mode..."
	@if command -v entr > /dev/null 2>&1; then \
		find $(VIEWS_PATH) -name "*.templ" | entr -r make dev; \
	else \
		echo "$(RED)[ERROR]$(NC) entr not found. Install with: brew install entr (macOS) or apt-get install entr (Linux)"; \
		exit 1; \
	fi

migrate: ## Run database migrations
	@echo "$(BLUE)[INFO]$(NC) Running database migrations..."
	@if [ -f $(BINARY_PATH) ]; then \
		$(BINARY_PATH) -migrate; \
	else \
		echo "$(RED)[ERROR]$(NC) Binary not found. Run 'make build' first"; \
		exit 1; \
	fi

seed: ## Seed database with sample data
	@echo "$(BLUE)[INFO]$(NC) Seeding database with sample data..."
	@if [ -f $(BINARY_PATH) ]; then \
		$(BINARY_PATH) -seed; \
	else \
		echo "$(RED)[ERROR]$(NC) Binary not found. Run 'make build' first"; \
		exit 1; \
	fi

db-reset: ## Reset database (drop and recreate)
	@echo "$(BLUE)[INFO]$(NC) Resetting database..."
	@rm -f $(DB_PATH)
	@$(MAKE) migrate
	@echo "$(GREEN)[SUCCESS]$(NC) Database reset completed"

docker-build: ## Build Docker image
	@echo "$(BLUE)[INFO]$(NC) Building Docker image..."
	@docker build -t tankstopp:latest .
	@echo "$(GREEN)[SUCCESS]$(NC) Docker image built successfully"

docker-run: ## Run application in Docker container
	@echo "$(BLUE)[INFO]$(NC) Running Docker container..."
	@docker run -p 8080:8080 -v $(PWD)/data:/app/data tankstopp:latest

docker-dev: ## Run Docker container in development mode
	@echo "$(BLUE)[INFO]$(NC) Running Docker container in development mode..."
	@docker run -p 8080:8080 -v $(PWD):/app -v $(PWD)/data:/app/data tankstopp:latest

lint: ## Run linters
	@echo "$(BLUE)[INFO]$(NC) Running linters..."
	@if command -v golangci-lint > /dev/null 2>&1; then \
		golangci-lint run; \
		echo "$(GREEN)[SUCCESS]$(NC) Linting completed"; \
	else \
		echo "$(YELLOW)[WARNING]$(NC) golangci-lint not found, skipping linting"; \
	fi

vet: ## Run go vet
	@echo "$(BLUE)[INFO]$(NC) Running go vet..."
	@$(GOCMD) vet ./...
	@echo "$(GREEN)[SUCCESS]$(NC) Vet completed"

mod-update: ## Update Go modules
	@echo "$(BLUE)[INFO]$(NC) Updating Go modules..."
	@$(GOGET) -u ./...
	@$(GOMOD) tidy
	@echo "$(GREEN)[SUCCESS]$(NC) Modules updated"

security: ## Run security scan
	@echo "$(BLUE)[INFO]$(NC) Running security scan..."
	@if command -v gosec > /dev/null 2>&1; then \
		gosec ./...; \
		echo "$(GREEN)[SUCCESS]$(NC) Security scan completed"; \
	else \
		echo "$(YELLOW)[WARNING]$(NC) gosec not found, skipping security scan"; \
	fi

benchmark: ## Run benchmarks
	@echo "$(BLUE)[INFO]$(NC) Running benchmarks..."
	@$(GOTEST) -bench=. -benchmem ./...
	@echo "$(GREEN)[SUCCESS]$(NC) Benchmarks completed"

all: ## Full build pipeline (format, generate, test, build)
	@echo "$(BLUE)[INFO]$(NC) Running full build pipeline..."
	@$(MAKE) format
	@$(MAKE) generate
	@$(MAKE) test
	@$(MAKE) build
	@echo "$(GREEN)[SUCCESS]$(NC) Full build pipeline completed"

check: ## Run all checks (format, vet, lint, test)
	@echo "$(BLUE)[INFO]$(NC) Running all checks..."
	@$(MAKE) format
	@$(MAKE) vet
	@$(MAKE) lint
	@$(MAKE) test
	@echo "$(GREEN)[SUCCESS]$(NC) All checks completed"

install-tools: ## Install development tools
	@echo "$(BLUE)[INFO]$(NC) Installing development tools..."
	@$(GOGET) -u github.com/a-h/templ/cmd/templ@latest
	@$(GOGET) -u github.com/cosmtrek/air@latest
	@$(GOGET) -u github.com/golangci/golangci-lint/cmd/golangci-lint@latest
	@$(GOGET) -u github.com/securecodewarrior/gosec/v2/cmd/gosec@latest
	@echo "$(GREEN)[SUCCESS]$(NC) Development tools installed"

version: ## Show version information
	@echo "TankStopp Build System"
	@echo "Go version: $$(go version)"
	@if command -v $(TEMPL_CMD) > /dev/null 2>&1; then \
		echo "Templ version: $$(templ version)"; \
	fi
	@if [ -f $(BINARY_PATH) ]; then \
		echo "Binary: $(BINARY_PATH)"; \
		echo "Size: $$(du -h $(BINARY_PATH) | cut -f1)"; \
	fi

clean-all: clean ## Clean everything including dependencies
	@echo "$(BLUE)[INFO]$(NC) Cleaning all artifacts and dependencies..."
	@$(GOMOD) clean -cache
	@echo "$(GREEN)[SUCCESS]$(NC) Everything cleaned"

# Docker targets
docker-build: ## Build Docker image
	@echo "$(BLUE)[INFO]$(NC) Building Docker image..."
	@./scripts/docker/build.sh --tag $(BINARY_NAME):latest --env production
	@echo "$(GREEN)[SUCCESS]$(NC) Docker image built successfully"

docker-build-dev: ## Build Docker image for development
	@echo "$(BLUE)[INFO]$(NC) Building development Docker image..."
	@./scripts/docker/build.sh --tag $(BINARY_NAME):dev --env development
	@echo "$(GREEN)[SUCCESS]$(NC) Development Docker image built successfully"

docker-run: ## Run Docker container
	@echo "$(BLUE)[INFO]$(NC) Running Docker container..."
	@docker run -d --name $(BINARY_NAME) -p 8080:8080 \
		-v tankstopp_data:/app/data \
		$(BINARY_NAME):latest
	@echo "$(GREEN)[SUCCESS]$(NC) Container started on http://localhost:8080"

docker-run-dev: ## Run Docker container in development mode
	@echo "$(BLUE)[INFO]$(NC) Running development Docker container..."
	@docker run -d --name $(BINARY_NAME)-dev -p 8081:8080 \
		-v tankstopp_dev_data:/app/data \
		-e TANKSTOPP_APP_DEBUG=true \
		$(BINARY_NAME):dev
	@echo "$(GREEN)[SUCCESS]$(NC) Development container started on http://localhost:8081"

docker-stop: ## Stop Docker container
	@echo "$(BLUE)[INFO]$(NC) Stopping Docker containers..."
	@docker stop $(BINARY_NAME) $(BINARY_NAME)-dev 2>/dev/null || true
	@docker rm $(BINARY_NAME) $(BINARY_NAME)-dev 2>/dev/null || true
	@echo "$(GREEN)[SUCCESS]$(NC) Docker containers stopped"

docker-logs: ## Show Docker container logs
	@echo "$(BLUE)[INFO]$(NC) Showing Docker logs..."
	@docker logs -f $(BINARY_NAME) 2>/dev/null || docker logs -f $(BINARY_NAME)-dev 2>/dev/null || echo "$(YELLOW)[WARNING]$(NC) No running containers found"

docker-clean: ## Clean Docker resources
	@echo "$(BLUE)[INFO]$(NC) Cleaning Docker resources..."
	@docker container prune -f
	@docker image prune -f
	@docker volume prune -f
	@docker network prune -f
	@echo "$(GREEN)[SUCCESS]$(NC) Docker cleanup completed"

docker-compose-up: ## Start services with docker-compose
	@echo "$(BLUE)[INFO]$(NC) Starting services with docker-compose..."
	@docker-compose up -d
	@echo "$(GREEN)[SUCCESS]$(NC) Services started"

docker-compose-down: ## Stop services with docker-compose
	@echo "$(BLUE)[INFO]$(NC) Stopping services with docker-compose..."
	@docker-compose down
	@echo "$(GREEN)[SUCCESS]$(NC) Services stopped"

docker-compose-logs: ## Show docker-compose logs
	@echo "$(BLUE)[INFO]$(NC) Showing docker-compose logs..."
	@docker-compose logs -f

docker-deploy: ## Deploy using deployment script
	@echo "$(BLUE)[INFO]$(NC) Deploying application..."
	@./scripts/docker/deploy.sh deploy --env production
	@echo "$(GREEN)[SUCCESS]$(NC) Application deployed"

docker-deploy-dev: ## Deploy development environment
	@echo "$(BLUE)[INFO]$(NC) Deploying development environment..."
	@./scripts/docker/deploy.sh deploy --env development
	@echo "$(GREEN)[SUCCESS]$(NC) Development environment deployed"

docker-status: ## Show Docker deployment status
	@echo "$(BLUE)[INFO]$(NC) Docker deployment status:"
	@./scripts/docker/deploy.sh status

docker-backup: ## Create database backup
	@echo "$(BLUE)[INFO]$(NC) Creating database backup..."
	@./scripts/docker/deploy.sh backup
	@echo "$(GREEN)[SUCCESS]$(NC) Database backup created"

docker-help: ## Show Docker deployment help
	@echo "$(BLUE)[INFO]$(NC) Docker deployment help:"
	@./scripts/docker/deploy.sh --help



# Development shortcuts
config-validate: build ## Validate configuration files
	@echo "$(BLUE)[INFO]$(NC) Validating configuration..."
	@if [ -f $(CONFIG_PATH) ]; then \
		echo "$(BLUE)[INFO]$(NC) Validating $(CONFIG_PATH)"; \
		TANKSTOPP_CONFIG_PATH=$(CONFIG_PATH) $(BINARY_PATH) --validate-config 2>/dev/null || echo "$(YELLOW)[WARNING]$(NC) Configuration validation not yet implemented"; \
	fi
	@if [ -f $(CONFIG_DEV_PATH) ]; then \
		echo "$(BLUE)[INFO]$(NC) Validating $(CONFIG_DEV_PATH)"; \
		TANKSTOPP_CONFIG_PATH=$(CONFIG_DEV_PATH) $(BINARY_PATH) --validate-config 2>/dev/null || echo "$(YELLOW)[WARNING]$(NC) Configuration validation not yet implemented"; \
	fi
	@if [ -f $(CONFIG_PROD_PATH) ]; then \
		echo "$(BLUE)[INFO]$(NC) Validating $(CONFIG_PROD_PATH)"; \
		TANKSTOPP_CONFIG_PATH=$(CONFIG_PROD_PATH) $(BINARY_PATH) --validate-config 2>/dev/null || echo "$(YELLOW)[WARNING]$(NC) Configuration validation not yet implemented"; \
	fi
	@echo "$(GREEN)[SUCCESS]$(NC) Configuration validation completed"

config-show: ## Show current configuration (without secrets)
	@echo "$(BLUE)[INFO]$(NC) Current configuration:"
	@echo "Config files found:"
	@if [ -f $(CONFIG_PATH) ]; then echo "  ✓ $(CONFIG_PATH)"; else echo "  ✗ $(CONFIG_PATH)"; fi
	@if [ -f $(CONFIG_DEV_PATH) ]; then echo "  ✓ $(CONFIG_DEV_PATH)"; else echo "  ✗ $(CONFIG_DEV_PATH)"; fi
	@if [ -f $(CONFIG_PROD_PATH) ]; then echo "  ✓ $(CONFIG_PROD_PATH)"; else echo "  ✗ $(CONFIG_PROD_PATH)"; fi
	@echo ""
	@echo "Environment variables:"
	@env | grep -E '^TANKSTOPP_|^DB_|^ENV=' | sort || echo "  No TankStopp environment variables set"

config-examples: ## Create example configuration files
	@echo "$(BLUE)[INFO]$(NC) Creating example configuration files..."
	@if [ ! -f $(CONFIG_PATH) ]; then \
		echo "$(BLUE)[INFO]$(NC) Creating $(CONFIG_PATH)"; \
		cp $(CONFIG_PATH) $(CONFIG_PATH).example 2>/dev/null || echo "$(YELLOW)[WARNING]$(NC) Default config not found"; \
	fi
	@if [ ! -f config.example.yaml ]; then \
		echo "$(BLUE)[INFO]$(NC) Creating config.example.yaml"; \
		cp $(CONFIG_PATH) config.example.yaml 2>/dev/null || echo "$(YELLOW)[WARNING]$(NC) Default config not found"; \
	fi
	@echo "$(GREEN)[SUCCESS]$(NC) Example configuration files created"

config-help: ## Show configuration documentation
	@echo "$(BLUE)[INFO]$(NC) TankStopp Configuration Help"
	@echo ""
	@echo "Configuration Files:"
	@echo "  config.yaml              - Default configuration"
	@echo "  config.development.yaml  - Development environment"
	@echo "  config.production.yaml   - Production environment"
	@echo ""
	@echo "Environment Variables (override config files):"
	@echo "  TANKSTOPP_CONFIG_PATH    - Custom config file path"
	@echo "  TANKSTOPP_SERVER_PORT    - Server port (default: 8081)"
	@echo "  TANKSTOPP_DATABASE_PATH  - Database file path"
	@echo "  TANKSTOPP_APP_DEBUG      - Enable debug mode (true/false)"
	@echo "  TANKSTOPP_APP_ENVIRONMENT - Environment (development/production/test)"
	@echo ""
	@echo "Legacy Environment Variables (still supported):"
	@echo "  DB_PATH                  - Database file path"
	@echo "  ENV                      - Environment name"
	@echo ""
	@echo "For complete documentation, see CONFIG_DOCUMENTATION.md"

run-dev: build ## Run in development mode with development config
	@echo "$(BLUE)[INFO]$(NC) Running in development mode..."
	@if [ -f $(CONFIG_DEV_PATH) ]; then \
		TANKSTOPP_CONFIG_PATH=$(CONFIG_DEV_PATH) $(BINARY_PATH); \
	else \
		TANKSTOPP_APP_ENVIRONMENT=development $(BINARY_PATH); \
	fi

run-prod: build ## Run in production mode with production config
	@echo "$(BLUE)[INFO]$(NC) Running in production mode..."
	@if [ -f $(CONFIG_PROD_PATH) ]; then \
		TANKSTOPP_CONFIG_PATH=$(CONFIG_PROD_PATH) $(BINARY_PATH); \
	else \
		TANKSTOPP_APP_ENVIRONMENT=production TANKSTOPP_APP_DEBUG=false $(BINARY_PATH); \
	fi

config-test: build ## Test configuration loading
	@echo "$(BLUE)[INFO]$(NC) Testing configuration loading..."
	@echo "Testing with default config:"
	@timeout 3 $(BINARY_PATH) 2>&1 | head -5 || true
	@echo ""
	@if [ -f $(CONFIG_DEV_PATH) ]; then \
		echo "Testing with development config:"; \
		timeout 3 TANKSTOPP_CONFIG_PATH=$(CONFIG_DEV_PATH) $(BINARY_PATH) 2>&1 | head -5 || true; \
		echo ""; \
	fi
	@echo "Testing with environment variables:"
	@timeout 3 TANKSTOPP_SERVER_PORT=9999 TANKSTOPP_APP_DEBUG=true $(BINARY_PATH) 2>&1 | head -5 || true

d: dev ## Alias for dev
b: build ## Alias for build
t: test ## Alias for test
c: clean ## Alias for clean
r: run ## Alias for run
rd: run-dev ## Alias for run-dev
rp: run-prod ## Alias for run-prod

# Docker aliases
db: docker-build ## Alias for docker-build
dr: docker-run ## Alias for docker-run
ds: docker-stop ## Alias for docker-stop
dl: docker-logs ## Alias for docker-logs
dc: docker-clean ## Alias for docker-clean
dd: docker-deploy ## Alias for docker-deploy
