.PHONY: help build test clean run-api run-executor run-worker run-sensor run-notifier \
        check fmt clippy install-tools db-create db-migrate db-reset docker-build \
        docker-up docker-down docker-cache-warm docker-stop-system-services dev watch generate-agents-index \
        docker-build-workers docker-build-worker-base docker-build-worker-python \
        docker-build-worker-node docker-build-worker-full deny ci-rust ci-web-blocking ci-web-advisory \
        ci-security-blocking ci-security-advisory ci-blocking ci-advisory \
        fmt-check pre-commit install-git-hooks \
        build-agent docker-build-agent run-agent run-agent-release \
        docker-up-agent docker-down-agent

# Default target
help:
	@echo "Attune Development Commands"
	@echo "==========================="
	@echo ""
	@echo "Building:"
	@echo "  make build          - Build all services"
	@echo "  make build-release  - Build all services in release mode"
	@echo "  make clean          - Clean build artifacts"
	@echo ""
	@echo "Testing:"
	@echo "  make test           - Run all tests"
	@echo "  make test-common    - Run tests for common library"
	@echo "  make test-api       - Run tests for API service"
	@echo "  make test-integration     - Run integration tests (common + API)"
	@echo "  make test-integration-api - Run API integration tests (requires DB)"
	@echo "  make check          - Check code without building"
	@echo ""
	@echo "Code Quality:"
	@echo "  make fmt            - Format all code"
	@echo "  make fmt-check      - Verify formatting without changing files"
	@echo "  make clippy         - Run linter"
	@echo "  make lint           - Run both fmt and clippy"
	@echo "  make deny           - Run cargo-deny checks"
	@echo "  make pre-commit     - Run the git pre-commit checks locally"
	@echo "  make install-git-hooks - Configure git to use the repo hook scripts"
	@echo ""
	@echo "Running Services:"
	@echo "  make run-api        - Run API service"
	@echo "  make run-executor   - Run executor service"
	@echo "  make run-worker     - Run worker service"
	@echo "  make run-sensor     - Run sensor service"
	@echo "  make run-notifier   - Run notifier service"
	@echo "  make dev            - Run all services in development mode"
	@echo ""
	@echo "Database:"
	@echo "  make db-create      - Create database"
	@echo "  make db-migrate     - Run migrations"
	@echo "  make db-reset       - Drop and recreate database"
	@echo "  make db-test-setup  - Setup test database"
	@echo "  make db-test-reset  - Reset test database"
	@echo ""
	@echo "Docker (Port conflicts? Run 'make docker-stop-system-services' first):"
	@echo "  make docker-stop-system-services - Stop system PostgreSQL/RabbitMQ/Redis"
	@echo "  make docker-cache-warm           - Pre-load build cache (prevents races)"
	@echo "  make docker-build                - Build Docker images"
	@echo "  make docker-build-workers        - Build all worker variants"
	@echo "  make docker-build-worker-base    - Build base worker (shell only)"
	@echo "  make docker-build-worker-python  - Build Python worker"
	@echo "  make docker-build-worker-node    - Build Node.js worker"
	@echo "  make docker-build-worker-full    - Build full worker (all runtimes)"
	@echo "  make docker-up                   - Start services with docker compose"
	@echo "  make docker-down                 - Stop services"
	@echo ""
	@echo "Agent (Universal Worker):"
	@echo "  make build-agent         - Build statically-linked agent binary (musl)"
	@echo "  make docker-build-agent  - Build agent Docker image"
	@echo "  make run-agent           - Run agent in development mode"
	@echo "  make run-agent-release   - Run agent in release mode"
	@echo "  make docker-up-agent     - Start all services + agent workers (ruby, etc.)"
	@echo "  make docker-down-agent   - Stop agent stack"
	@echo ""
	@echo "Development:"
	@echo "  make watch          - Watch and rebuild on changes"
	@echo "  make install-tools  - Install development tools"
	@echo ""
	@echo "Documentation:"
	@echo "  make generate-agents-index - Generate AGENTS.md index for AI agents"
	@echo ""

# Increase rustc stack size to prevent SIGSEGV during compilation
export RUST_MIN_STACK:=67108864

# Building
build:
	cargo build

build-release:
	cargo build --release

clean:
	cargo clean

# Testing
test:
	cargo test

test-common:
	cargo test -p attune-common

test-api:
	cargo test -p attune-api

test-verbose:
	cargo test -- --nocapture --test-threads=1

test-integration: test-integration-api
	@echo "Setting up test database..."
	@make db-test-setup
	@echo "Running common integration tests..."
	cargo test --test '*' -p attune-common -- --test-threads=1
	@echo "Integration tests complete"

test-integration-api:
	@echo "Running API integration tests..."
	cargo test -p attune-api -- --ignored --test-threads=1
	@echo "API integration tests complete"

test-with-db: db-test-setup test-integration
	@echo "All tests with database complete"

# Code quality
check:
	cargo check --all-features

fmt:
	cargo fmt --all

fmt-check:
	cargo fmt --all -- --check

clippy:
	cargo clippy --all-features -- -D warnings

lint: fmt clippy

# Running services
run-api:
	cargo run --bin attune-api

run-api-release:
	cargo run --bin attune-api --release

run-executor:
	cargo run --bin attune-executor

run-executor-release:
	cargo run --bin attune-executor --release

run-worker:
	cargo run --bin attune-worker

run-worker-release:
	cargo run --bin attune-worker --release

run-sensor:
	cargo run --bin attune-sensor

run-sensor-release:
	cargo run --bin attune-sensor --release

run-notifier:
	cargo run --bin attune-notifier

run-notifier-release:
	cargo run --bin attune-notifier --release

# Development mode (run all services)
dev:
	@echo "Starting all services in development mode..."
	@echo "Note: Run each service in a separate terminal or use docker compose"
	@echo ""
	@echo "Terminal 1: make run-api"
	@echo "Terminal 2: make run-executor"
	@echo "Terminal 3: make run-worker"
	@echo "Terminal 4: make run-sensor"
	@echo "Terminal 5: make run-notifier"

# Watch for changes and rebuild
watch:
	cargo watch -x check -x test -x build

# Database operations
db-create:
	createdb attune || true

db-migrate:
	sqlx migrate run

db-drop:
	dropdb attune || true

db-reset: db-drop db-create db-migrate
	@echo "Database reset complete"

# Test database operations
db-test-create:
	psql postgresql://postgres:postgres@localhost:5432 -c "CREATE DATABASE attune_test"

db-test-migrate:
	DATABASE_URL=postgresql://postgres:postgres@localhost:5432/attune_test sqlx migrate run

db-test-drop:
	psql postgresql://postgres:postgres@localhost:5432 -c "DROP DATABASE attune_test"

db-test-reset: db-test-drop db-test-create db-test-migrate
	@echo "Test database reset complete"

db-test-setup: db-test-create db-test-migrate
	@echo "Test database setup complete"

# Docker operations

# Stop system services that conflict with Docker Compose
# This resolves "address already in use" errors for PostgreSQL (5432), RabbitMQ (5672), Redis (6379)
docker-stop-system-services:
	@echo "Stopping system services that conflict with Docker..."
	@./scripts/stop-system-services.sh

# Pre-warm the build cache by building one service first
# This prevents race conditions when building multiple services in parallel
# The first build populates the shared cargo registry/git cache
docker-cache-warm:
	@echo "Warming up build cache (building API service first)..."
	@echo "This prevents race conditions during parallel builds."
	docker compose build api
	@echo ""
	@echo "Cache warmed! Now you can safely run 'make docker-build' for parallel builds."

docker-build:
	@echo "Building Docker images..."
	docker compose build

docker-build-api:
	docker compose build api

docker-build-web:
	docker compose build web

# Agent binary (statically-linked for injection into any container)
AGENT_RUST_TARGET ?= x86_64-unknown-linux-musl

build-agent:
	@echo "Installing musl target (if not already installed)..."
	rustup target add $(AGENT_RUST_TARGET) 2>/dev/null || true
	@echo "Building statically-linked worker and sensor agent binaries..."
	SQLX_OFFLINE=true cargo build --release --target $(AGENT_RUST_TARGET) --bin attune-agent --bin attune-sensor-agent
	strip target/$(AGENT_RUST_TARGET)/release/attune-agent
	strip target/$(AGENT_RUST_TARGET)/release/attune-sensor-agent
	@echo "✅ Agent binaries built:"
	@echo "   - target/$(AGENT_RUST_TARGET)/release/attune-agent"
	@echo "   - target/$(AGENT_RUST_TARGET)/release/attune-sensor-agent"
	@ls -lh target/$(AGENT_RUST_TARGET)/release/attune-agent
	@ls -lh target/$(AGENT_RUST_TARGET)/release/attune-sensor-agent

docker-build-agent:
	@echo "Building agent Docker image (statically-linked binary)..."
	DOCKER_BUILDKIT=1 docker buildx build --build-arg RUST_TARGET=$(AGENT_RUST_TARGET) --target agent-init -f docker/Dockerfile.agent -t attune-agent:latest .
	@echo "✅ Agent image built: attune-agent:latest"

run-agent:
	cargo run --bin attune-agent

run-agent-release:
	cargo run --bin attune-agent --release

run-sensor-agent:
	cargo run --bin attune-sensor-agent

run-sensor-agent-release:
	cargo run --bin attune-sensor-agent --release

docker-up:
	@echo "Starting all services with Docker Compose..."
	docker compose up -d

docker-up-agent:
	@echo "Starting all services + agent-based workers..."
	docker compose -f docker-compose.yaml -f docker-compose.agent.yaml up -d

docker-down:
	@echo "Stopping all services..."
	docker compose down

docker-down-agent:
	@echo "Stopping all services (including agent workers)..."
	docker compose -f docker-compose.yaml -f docker-compose.agent.yaml down

docker-down-volumes:
	@echo "Stopping all services and removing volumes (WARNING: deletes data)..."
	docker compose down -v

docker-restart:
	docker compose restart

docker-logs:
	docker compose logs -f

docker-logs-api:
	docker compose logs -f api

docker-ps:
	docker compose ps

docker-shell-api:
	docker compose exec api /bin/sh

docker-shell-db:
	docker compose exec postgres psql -U attune

docker-clean:
	@echo "Cleaning up Docker resources..."
	docker compose down -v --rmi local
	docker system prune -f

# Install development tools
install-tools:
	@echo "Installing development tools..."
	cargo install cargo-watch
	cargo install cargo-expand
	cargo install sqlx-cli --no-default-features --features postgres
	@echo "Tools installed successfully"

# Setup environment
setup: install-tools
	@echo "Setting up development environment..."
	@if [ ! -f .env ]; then \
		echo "Creating .env file from .env.example..."; \
		cp .env.example .env; \
		echo "⚠️  Please edit .env and update configuration values"; \
	fi
	@if [ ! -f .env.test ]; then \
		echo ".env.test already exists"; \
	fi
	@echo "Setup complete! Run 'make db-create && make db-migrate' to initialize the database."
	@echo "For testing, run 'make db-test-setup' to initialize the test database."

# Documentation
docs:
	cargo doc --no-deps --open

# Generate AGENTS.md index
generate-agents-index:
	@echo "Generating AGENTS.md index..."
	python3 scripts/generate_agents_md_index.py
	@echo "✅ AGENTS.md generated successfully"

# Benchmarks
bench:
	cargo bench

# Coverage
coverage:
	cargo tarpaulin --out Html --output-dir coverage

# Update dependencies
update:
	cargo update

# Audit dependencies for security issues (ignores configured in deny.toml)
audit:
	cargo deny check advisories

deny:
	cargo deny check

ci-rust:
	cargo fmt --all -- --check
	cargo clippy --workspace --all-targets --all-features -- -D warnings
	cargo test --workspace --all-features
	cargo deny check

ci-web-blocking:
	cd web && npm ci
	cd web && npm run lint
	cd web && npm run typecheck
	cd web && npm run build

ci-web-pre-commit:
	cd web && npm ci
	cd web && npm run lint
	cd web && npm run typecheck

ci-web-advisory:
	cd web && npm ci
	cd web && npm run knip
	cd web && npm audit --omit=dev

ci-security-blocking:
	mkdir -p $$HOME/bin
	GITLEAKS_VERSION="8.24.2"; \
	ARCH="$$(uname -m)"; \
	case "$$ARCH" in \
		x86_64) ARCH="x64" ;; \
		aarch64|arm64) ARCH="arm64" ;; \
		*) echo "Unsupported architecture: $$ARCH"; exit 1 ;; \
	esac; \
	curl -sSfL \
		-o /tmp/gitleaks.tar.gz \
		"https://github.com/gitleaks/gitleaks/releases/download/v$$GITLEAKS_VERSION/gitleaks_$$GITLEAKS_VERSION"_linux_"$$ARCH".tar.gz; \
	tar -xzf /tmp/gitleaks.tar.gz -C $$HOME/bin gitleaks; \
	chmod +x $$HOME/bin/gitleaks
	$$HOME/bin/gitleaks git --report-format sarif --report-path gitleaks.sarif --config .gitleaks.toml

ci-security-advisory:
	pip install semgrep
	semgrep scan --config p/default --error

ci-blocking: ci-rust ci-web-blocking ci-security-blocking
	@echo "✅ Blocking CI checks passed!"

ci-advisory: ci-web-advisory ci-security-advisory
	@echo "Advisory CI checks complete."

# Check dependency tree
tree:
	cargo tree

# Generate licenses list
licenses:
	cargo license --json > licenses.json
	@echo "License information saved to licenses.json"

# Blocking checks run by the git pre-commit hook after formatting.
# Keep the local web step fast; full production builds stay in CI.
pre-commit: deny ci-web-pre-commit ci-security-blocking
	@echo "✅ Pre-commit checks passed."

install-git-hooks:
	git config core.hooksPath .githooks
	chmod +x .githooks/pre-commit
	@echo "✅ Git hooks configured to use .githooks/"

# CI simulation
ci: ci-blocking ci-advisory
	@echo "✅ CI checks passed!"
