# Variables
BINARY_NAME := query-engine
BINARY := target/release/$(BINARY_NAME)
DEBUG_PROJ := 0
RUST_BACKTRACE := 1

# Default target
.DEFAULT_GOAL := help

.PHONY: help
help: ## Show help messages for all available targets
	@grep -E '^[a-zA-Z_-]+:.*## .*$$' Makefile | \
	awk 'BEGIN {FS = ":.*## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

.PHONY: format
format: ## Format Rust files
	@echo "Formatting Rust files..."
	@cargo fmt

.PHONY: test
test: format ## Run the tests
	@echo "Running tests..."
	@DEBUG_PROJ=$(DEBUG_PROJ) RUST_BACKTRACE=$(RUST_BACKTRACE) cargo test --all-targets --workspace -- --nocapture

.PHONY: coverage
coverage: format ## Generate test coverage report
	@echo "Generating test coverage report..."
	@DEBUG_PROJ=$(DEBUG_PROJ) cargo tarpaulin --out Xml --out Html

.PHONY: build
build: format ## Build the binary for the current platform
	@echo "Building the project..."
	@DEBUG_PROJ=$(DEBUG_PROJ) cargo build --release

.PHONY: run
run: build ## Build and run the binary
	@echo "Running the $(BINARY) binary..."
	@DEBUG_PROJ=$(DEBUG_PROJ) ./$(BINARY)

.PHONY: repl
repl: format ## Start the interactive REPL
	@echo "Starting query-engine REPL..."
	@DEBUG_PROJ=$(DEBUG_PROJ) cargo run -- repl

.PHONY: gui
gui: format ## Start the local GUI at 127.0.0.1:7878
	@echo "Starting query-engine GUI on http://127.0.0.1:7878..."
	@DEBUG_PROJ=$(DEBUG_PROJ) cargo run -- gui

.PHONY: gui-addr
gui-addr: format ## Start the local GUI at GUI_ADDR=<host:port>
	@echo "Starting query-engine GUI on http://$(or $(GUI_ADDR),127.0.0.1:7878)..."
	@DEBUG_PROJ=$(DEBUG_PROJ) cargo run -- gui $(or $(GUI_ADDR),127.0.0.1:7878)

.PHONY: script
script: format ## Run a frontend script with SCRIPT=<path>
	@if [ -z "$(SCRIPT)" ]; then \
	   echo "Usage: make script SCRIPT=<path>"; \
	   exit 1; \
	fi
	@echo "Running script $(SCRIPT)..."
	@DEBUG_PROJ=$(DEBUG_PROJ) cargo run -- script $(SCRIPT)

.PHONY: clean
clean: ## Remove generated and temporary files
	@echo "Cleaning up..."
	@cargo clean

.PHONY: install-deps
install-deps: ## Install development dependencies
	@echo "Installing dependencies..."
	@rustup component add rustfmt clippy
	@cargo install cargo-tarpaulin
	@cargo install cargo-audit
	@cargo install cargo-nextest

.PHONY: lint
lint: format ## Run the linters
	@echo "Linting Rust files..."
	@DEBUG_PROJ=$(DEBUG_PROJ) cargo clippy -- -D warnings -D clippy::unwrap_used -D clippy::expect_used

.PHONY: audit
audit: ## Run security audit on Rust dependencies
	@echo "Running security audit..."
	@cargo audit

.PHONY: docs
docs: format ## Generate the documentation
	@echo "Generating documentation..."
	@cargo doc --no-deps --document-private-items

.PHONY: fix-lint
fix-lint: ## Fix the linter warnings
	@echo "Fixing linter warnings..."
	@cargo clippy --fix --allow-dirty --allow-staged --all-targets --workspace

.PHONY: nextest
nextest: ## Run tests using nextest
	@echo "Running tests using nextest..."
	@DEBUG_PROJ=$(DEBUG_PROJ) RUST_BACKTRACE=$(RUST_BACKTRACE) cargo nextest run

.PHONY: setup-hooks
setup-hooks: ## Install Git hooks (pre-commit)
	@echo "Setting up Git hooks..."
	@if ! command -v pre-commit &> /dev/null; then \
	   echo "pre-commit not found. Please install it using 'pip install pre-commit'"; \
	   exit 1; \
	fi
	@pre-commit install --hook-type pre-commit
	@pre-commit install --hook-type pre-push
	@pre-commit install-hooks

.PHONY: test-hooks
test-hooks: ## Test Git hooks on all files
	@echo "Testing Git hooks..."
	@pre-commit run --all-files --show-diff-on-failure

.PHONY: check
check: format lint test ## Run format, lint, and test
	@echo "All checks passed."
