# DSOL - Document Semantic Overload Layer
# Makefile for common development tasks

.PHONY: help install setup start stop clean test api worker services logs

# Default target
.DEFAULT_GOAL := help

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

##@ Help

help: ## Display this help message
	@echo "$(BLUE)DSOL - Document Semantic Overload Layer$(NC)"
	@echo ""
	@echo "$(GREEN)Available targets:$(NC)"
	@awk 'BEGIN {FS = ":.*##"; printf "\n"} /^[a-zA-Z_-]+:.*?##/ { printf "  $(YELLOW)%-20s$(NC) %s\n", $$1, $$2 } /^##@/ { printf "\n$(BLUE)%s$(NC)\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ Setup & Installation

install: ## Install dependencies with uv
	@echo "$(GREEN)Installing dependencies...$(NC)"
	uv sync --all-extras

setup: install ## Complete setup (install + start infrastructure + migrations)
	@echo "$(GREEN)Setting up infrastructure...$(NC)"
	docker compose up -d
	@echo "$(YELLOW)Waiting for services to be healthy...$(NC)"
	@sleep 5
	@echo "$(GREEN)Running database migrations...$(NC)"
	uv run alembic upgrade head
	@echo "$(GREEN)Setup complete!$(NC)"

##@ Infrastructure

services: ## Start infrastructure services (PostgreSQL, Redis, Milvus)
	@echo "$(GREEN)Starting infrastructure services...$(NC)"
	docker compose up -d
	@echo "$(YELLOW)Waiting for services to be healthy...$(NC)"
	@sleep 3
	docker compose ps

services-stop: ## Stop infrastructure services
	@echo "$(YELLOW)Stopping infrastructure services...$(NC)"
	docker compose down

services-restart: ## Restart infrastructure services
	@echo "$(YELLOW)Restarting infrastructure services...$(NC)"
	docker compose restart

services-logs: ## Show logs from infrastructure services
	docker compose logs -f

services-ps: ## Show status of infrastructure services
	docker compose ps

##@ Database

migrate: ## Run database migrations
	@echo "$(GREEN)Running database migrations...$(NC)"
	uv run alembic upgrade head

migrate-down: ## Rollback last database migration
	@echo "$(YELLOW)Rolling back last migration...$(NC)"
	uv run alembic downgrade -1

migrate-history: ## Show migration history
	uv run alembic history

migrate-current: ## Show current migration version
	uv run alembic current

##@ Application

api: ## Start API server (development mode with reload)
	@echo "$(GREEN)Starting API server on http://localhost:8000$(NC)"
	@echo "$(BLUE)API Docs: http://localhost:8000/docs$(NC)"
	uv run uvicorn src.api.main:app --reload --host 0.0.0.0 --port 8000

api-prod: ## Start API server (production mode, 4 workers)
	@echo "$(GREEN)Starting API server in production mode...$(NC)"
	uv run uvicorn src.api.main:app --host 0.0.0.0 --port 8000 --workers 4

worker: ## Start Celery worker (development mode)
	@echo "$(GREEN)Starting Celery worker...$(NC)"
	uv run celery -A src.workers.celery_app worker --loglevel=info

worker-debug: ## Start Celery worker with debug logging
	@echo "$(GREEN)Starting Celery worker (debug mode)...$(NC)"
	uv run celery -A src.workers.celery_app worker --loglevel=debug

worker-prod: ## Start Celery worker (production mode, 4 concurrent tasks)
	@echo "$(GREEN)Starting Celery worker in production mode...$(NC)"
	uv run celery -A src.workers.celery_app worker --loglevel=warning --concurrency=4

worker-inspect: ## Inspect active Celery tasks
	uv run celery -A src.workers.celery_app inspect active

worker-registered: ## Show registered Celery tasks
	uv run celery -A src.workers.celery_app inspect registered

worker-events: ## Monitor Celery events in real-time
	uv run celery -A src.workers.celery_app events

##@ Development - Start Everything

dev: services ## Start all services for development (infrastructure + API + worker in background)
	@echo "$(GREEN)Starting development environment...$(NC)"
	@echo "$(YELLOW)Infrastructure services starting...$(NC)"
	@sleep 3
	@echo "$(GREEN)Starting API server in background...$(NC)"
	@nohup uv run uvicorn src.api.main:app --reload --host 0.0.0.0 --port 8000 > logs/api.log 2>&1 &
	@echo $$! > .api.pid
	@echo "$(GREEN)Starting Celery worker in background...$(NC)"
	@nohup uv run celery -A src.workers.celery_app worker --loglevel=info > logs/worker.log 2>&1 &
	@echo $$! > .worker.pid
	@echo ""
	@echo "$(GREEN)Development environment started!$(NC)"
	@echo "$(BLUE)API: http://localhost:8000$(NC)"
	@echo "$(BLUE)Docs: http://localhost:8000/docs$(NC)"
	@echo ""
	@echo "$(YELLOW)Logs:$(NC)"
	@echo "  API:    tail -f logs/api.log"
	@echo "  Worker: tail -f logs/worker.log"
	@echo ""
	@echo "$(YELLOW)Stop with: make stop$(NC)"

start: dev ## Alias for 'make dev'

stop: ## Stop all background services (API + worker + infrastructure)
	@echo "$(YELLOW)Stopping development environment...$(NC)"
	@if [ -f .api.pid ]; then \
		kill -9 $$(cat .api.pid) 2>/dev/null || true; \
		rm .api.pid; \
		echo "$(GREEN)API server stopped$(NC)"; \
	fi
	@if [ -f .worker.pid ]; then \
		kill -9 $$(cat .worker.pid) 2>/dev/null || true; \
		rm .worker.pid; \
		echo "$(GREEN)Celery worker stopped$(NC)"; \
	fi
	@pkill -f "uvicorn src.api.main:app" 2>/dev/null || true
	@pkill -f "celery -A src.workers.celery_app worker" 2>/dev/null || true
	@echo "$(GREEN)All services stopped$(NC)"

restart: stop dev ## Restart all services

status: ## Show status of all services
	@echo "$(BLUE)Infrastructure Services:$(NC)"
	@docker compose ps
	@echo ""
	@echo "$(BLUE)Application Processes:$(NC)"
	@ps aux | grep -E "(uvicorn|celery)" | grep -v grep || echo "  No running processes"

logs: ## Show logs from all services
	@echo "$(BLUE)Recent API logs:$(NC)"
	@tail -20 logs/api.log 2>/dev/null || echo "  No API logs yet"
	@echo ""
	@echo "$(BLUE)Recent Worker logs:$(NC)"
	@tail -20 logs/worker.log 2>/dev/null || echo "  No worker logs yet"

logs-api: ## Tail API server logs
	tail -f logs/api.log

logs-worker: ## Tail Celery worker logs
	tail -f logs/worker.log

##@ Testing

test: ## Run all tests
	@echo "$(GREEN)Running tests...$(NC)"
	uv run pytest

test-cov: ## Run tests with coverage
	@echo "$(GREEN)Running tests with coverage...$(NC)"
	uv run pytest --cov=src

test-file: ## Run specific test file (usage: make test-file FILE=tests/test_api/test_health.py)
	@echo "$(GREEN)Running test: $(FILE)$(NC)"
	uv run pytest $(FILE)

test-pipeline: ## Test extraction pipeline manually
	@echo "$(GREEN)Running manual pipeline test...$(NC)"
	uv run python test_pipeline_manual.py

test-batch: ## Run batch extraction on CustomerDocument/
	@echo "$(GREEN)Running batch extraction...$(NC)"
	uv run python batch_extract_v2.py

test-batch-resume: ## Resume interrupted batch extraction
	@echo "$(GREEN)Resuming batch extraction...$(NC)"
	uv run python batch_extract_v2.py --resume

##@ Cleanup

clean: ## Clean up temporary files, caches, and logs
	@echo "$(YELLOW)Cleaning up temporary files...$(NC)"
	find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
	find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true
	find . -type d -name "*.egg-info" -exec rm -rf {} + 2>/dev/null || true
	find . -type f -name "*.pyc" -delete 2>/dev/null || true
	find . -type f -name "*.pyo" -delete 2>/dev/null || true
	find . -type f -name ".coverage" -delete 2>/dev/null || true
	rm -rf .api.pid .worker.pid
	rm -rf logs/*.log 2>/dev/null || true
	@echo "$(GREEN)Cleanup complete$(NC)"

clean-all: clean services-stop ## Clean everything and stop all services
	@echo "$(YELLOW)Removing all data volumes...$(NC)"
	docker compose down -v
	@echo "$(GREEN)Complete cleanup done$(NC)"

reset: clean-all setup ## Reset entire environment (clean + setup from scratch)
	@echo "$(GREEN)Environment reset complete!$(NC)"

##@ Utilities

check-prereqs: ## Check if all prerequisites are installed
	@echo "$(BLUE)Checking prerequisites...$(NC)"
	@command -v python3 >/dev/null 2>&1 && echo "$(GREEN)✓ Python3 installed$(NC)" || echo "$(RED)✗ Python3 not found$(NC)"
	@command -v docker >/dev/null 2>&1 && echo "$(GREEN)✓ Docker installed$(NC)" || echo "$(RED)✗ Docker not found$(NC)"
	@command -v docker compose >/dev/null 2>&1 && echo "$(GREEN)✓ Docker Compose installed$(NC)" || echo "$(RED)✗ Docker Compose not found$(NC)"
	@command -v uv >/dev/null 2>&1 && echo "$(GREEN)✓ uv installed$(NC)" || echo "$(RED)✗ uv not found$(NC)"
	@command -v libreoffice >/dev/null 2>&1 && echo "$(GREEN)✓ LibreOffice installed$(NC)" || echo "$(YELLOW)⚠ LibreOffice not found (optional for .xls/.xlsm)$(NC)"

init-logs: ## Create logs directory
	@mkdir -p logs
	@touch logs/api.log logs/worker.log

env-example: ## Create .env from .env.example if it doesn't exist
	@if [ ! -f .env ]; then \
		echo "$(YELLOW)Creating .env from .env.example...$(NC)"; \
		cp .env.example .env; \
		echo "$(GREEN).env created! Please edit it with your credentials.$(NC)"; \
	else \
		echo "$(BLUE).env already exists$(NC)"; \
	fi

##@ Quick Start

quickstart: check-prereqs env-example install init-logs setup ## Complete quickstart setup from scratch
	@echo ""
	@echo "$(GREEN)═══════════════════════════════════════════$(NC)"
	@echo "$(GREEN)  DSOL Setup Complete!$(NC)"
	@echo "$(GREEN)═══════════════════════════════════════════$(NC)"
	@echo ""
	@echo "$(BLUE)Next steps:$(NC)"
	@echo "  1. Edit .env with your Azure OpenAI credentials"
	@echo "  2. Start development: $(YELLOW)make dev$(NC)"
	@echo "  3. Access API docs: $(BLUE)http://localhost:8000/docs$(NC)"
	@echo ""
	@echo "$(YELLOW)Useful commands:$(NC)"
	@echo "  make status    - Check service status"
	@echo "  make logs      - View recent logs"
	@echo "  make stop      - Stop all services"
	@echo "  make help      - Show all commands"
	@echo ""
