# SPDX-License-Identifier: Apache-2.0
# Makefile for MLX-LLM development and build tasks

.PHONY: help install install-dev test test-unit test-integration lint format clean build build-all dist upload docs \
	cmake-check cmake-setup cmake-configure cmake-build cmake-install cmake-clean cmake-rebuild cmake-all cmake-info \
	cmake-detect-m4 cmake-extensions cmake-test-build cmake-check-deps cmake-metalcutlass \
	docker-build docker-build-dev docker-build-all docker-up docker-down docker-restart \
	docker-logs docker-shell docker-test docker-clean docker-prune docker-info \
	env-check env-info env-create-conda env-create-venv env-activate-help env-install-prod \
	env-install-dev env-install-all env-install-packages env-install-packages-dev env-setup-complete env-clean env-reset

# Default target
.DEFAULT_GOAL := help

# Python interpreter
PYTHON := /Users/ryanoboyle/miniforge3/envs/mlxllm/bin/python
PIP := $(PYTHON) -m pip

# Package info
PACKAGE := mlxllm
SRC_DIR := .
TEST_DIR := tests
DOCS_DIR := docs
DOCS_BUILD_DIR := $(DOCS_DIR)/build
DOCS_SOURCE_DIR := $(DOCS_DIR)/source

# CMake configuration
CMAKE := cmake
CMAKE_BUILD_DIR := build/cmake
CMAKE_INSTALL_PREFIX := $(shell $(PYTHON) -c "import sys; print(sys.prefix)")
CSRC_DIR := csrc

help:  ## Show this help message
	@echo "=========================================="
	@echo "MLX-LLM Development Makefile"
	@echo "=========================================="
	@echo ""
	@echo "Available targets:"
	@echo ""
	@echo "\033[1mInstallation:\033[0m"
	@grep -E '^install.*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "\033[1mTesting:\033[0m"
	@grep -E '^(test|coverage).*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "\033[1mCode Quality:\033[0m"
	@grep -E '^(lint|format|type-check).*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "\033[1mBuild & Distribution:\033[0m"
	@grep -E '^(build|dist|sdist|wheel|clean|upload|check-dist).*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "\033[1mCMake Build System:\033[0m"
	@grep -E '^cmake-.*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "\033[1mDocumentation:\033[0m"
	@grep -E '^docs.*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "\033[1mDevelopment:\033[0m"
	@grep -E '^(dev-setup|verify|info|shell|watch-tests|benchmark|profile).*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "\033[1mEnvironment:\033[0m"
	@grep -E '^env-.*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "\033[1mRequirements:\033[0m"
	@grep -E '^requirements-.*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "\033[1mDocker:\033[0m"
	@grep -E '^docker-.*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-24s\033[0m %s\n", $$1, $$2}'
	@echo ""
	@echo "For more information, see: docs/dev/AUTOMATED_BUILD_GUIDE.md"
	@echo "=========================================="

install:  ## Install package in production mode (installs metalcutlass first)
	@echo "Installing metalcutlass first..."
	cd packages/metalcutlass && $(PIP) install --no-build-isolation -e .
	@echo "Installing mlxllm..."
	$(PIP) install -e .

install-dev:  ## Install package with development dependencies (installs metalcutlass first)
	@echo "Installing metalcutlass first..."
	cd packages/metalcutlass && $(PIP) install --no-build-isolation -e .
	@echo "Installing mlxllm with dev dependencies..."
	$(PIP) install -e ".[dev]"

install-test:  ## Install package with test dependencies (installs metalcutlass first)
	@echo "Installing metalcutlass first..."
	cd packages/metalcutlass && $(PIP) install --no-build-isolation -e .
	@echo "Installing mlxllm with test dependencies..."
	$(PIP) install -e ".[test]"

install-all:  ## Install package with all optional dependencies (installs metalcutlass first)
	@echo "Installing metalcutlass first..."
	cd packages/metalcutlass && $(PIP) install --no-build-isolation -e .
	@echo "Installing mlxllm with all dependencies..."
	$(PIP) install -e ".[dev,test,docs]"

install-auto:  ## Automated installation using install.sh script
	bash install.sh

install-auto-dev:  ## Automated installation with dev dependencies
	bash install.sh dev

test:  ## Run all tests with coverage
	$(PYTHON) -m pytest $(TEST_DIR) -v --cov=$(PACKAGE) --cov-report=term-missing --cov-report=html

test-unit:  ## Run unit tests only
	$(PYTHON) -m pytest $(TEST_DIR)/unit -v -m "not slow and not requires_metal"

test-integration:  ## Run integration tests
	$(PYTHON) -m pytest $(TEST_DIR)/integration -v

test-slow:  ## Run slow tests
	$(PYTHON) -m pytest $(TEST_DIR) -v -m slow

test-metal:  ## Run tests requiring Metal GPU
	$(PYTHON) -m pytest $(TEST_DIR) -v -m requires_metal

test-quick:  ## Run quick tests (unit tests without slow/metal)
	$(PYTHON) -m pytest $(TEST_DIR) -v -m "not slow and not requires_metal" --tb=short

coverage:  ## Generate coverage report
	$(PYTHON) -m pytest $(TEST_DIR) --cov=$(PACKAGE) --cov-report=html --cov-report=term
	@echo "Coverage report generated in htmlcov/index.html"

lint:  ## Run all linters
	$(PYTHON) -m ruff check $(SRC_DIR)
	$(PYTHON) -m mypy $(PACKAGE)
	$(PYTHON) -m black --check $(SRC_DIR)

lint-fix:  ## Run linters and auto-fix issues
	$(PYTHON) -m ruff check --fix $(SRC_DIR)
	$(PYTHON) -m black $(SRC_DIR)

format:  ## Format code with black and isort
	$(PYTHON) -m black $(SRC_DIR)
	$(PYTHON) -m isort $(SRC_DIR)

type-check:  ## Run type checking with mypy
	$(PYTHON) -m mypy $(PACKAGE)

clean:  ## Clean build artifacts and caches
	rm -rf build/
	rm -rf dist/
	rm -rf *.egg-info/
	rm -rf .pytest_cache/
	rm -rf .mypy_cache/
	rm -rf .ruff_cache/
	rm -rf htmlcov/
	rm -rf .coverage
	find . -type d -name __pycache__ -exec rm -rf {} +
	find . -type f -name '*.pyc' -delete
	find . -type f -name '*.pyo' -delete
	find . -type f -name '*~' -delete
	@echo "Cleaned Python build artifacts"

clean-all: clean cmake-clean  ## Clean all generated files including CMake build artifacts
	rm -rf venv/
	rm -rf .venv/
	@echo "Cleaned all build artifacts"

build:  ## Build source and wheel distributions
	$(PYTHON) -m build

dist: clean build  ## Build distribution packages

sdist:  ## Build source distribution only
	$(PYTHON) setup.py sdist

wheel:  ## Build wheel distribution only
	$(PYTHON) setup.py bdist_wheel

install-build:  ## Install build dependencies
	$(PIP) install build wheel setuptools

check-dist:  ## Check distribution packages
	$(PYTHON) -m twine check dist/*

upload-test:  ## Upload to TestPyPI
	$(PYTHON) -m twine upload --repository testpypi dist/*

upload:  ## Upload to PyPI (use with caution!)
	$(PYTHON) -m twine upload dist/*

build-all:  ## Complete build: metalcutlass + CMake C++ extensions + Python packages + docs
	@echo "=========================================="
	@echo "Complete Build Process"
	@echo "=========================================="
	@echo ""
	@echo "Step 1/6: Cleaning previous builds..."
	@$(MAKE) clean
	@echo ""
	@echo "Step 2/6: Building metalcutlass..."
	@cd packages/metalcutlass && $(PYTHON) -m pip install --no-build-isolation -e .
	@echo ""
	@echo "Step 3/6: Building C++ extensions with CMake..."
	@if [ ! -d "$(CMAKE_BUILD_DIR)" ]; then \
		echo "Configuring CMake..."; \
		$(MAKE) cmake-configure; \
	fi
	@echo "Building C++ extensions..."
	@$(MAKE) cmake-build
	@echo "Installing C++ extensions..."
	@$(MAKE) cmake-install
	@echo ""
	@echo "Step 4/6: Building Python distributions..."
	@$(PYTHON) -m build
	@echo ""
	@echo "Step 5/6: Installing mlxllm..."
	@$(PIP) install -e ".[dev]"
	@echo ""
	@echo "Step 6/6: Building documentation..."
	@if [ -d "$(DOCS_SOURCE_DIR)" ]; then \
		$(MAKE) docs 2>/dev/null || echo "⚠️  Documentation build failed (non-critical)"; \
	else \
		echo "⚠️  Documentation source not found. Skipping."; \
	fi
	@echo ""
	@echo "=========================================="
	@echo "✅ Build complete!"
	@echo "=========================================="
	@echo ""
	@echo "Built artifacts:"
	@echo "  - Python wheel: dist/*.whl"
	@echo "  - Source dist: dist/*.tar.gz"
	@echo "  - C++ extensions: $(CMAKE_BUILD_DIR)"
	@if [ -d "$(DOCS_BUILD_DIR)/html" ]; then \
		echo "  - Documentation: $(DOCS_BUILD_DIR)/html/index.html"; \
	fi
	@echo ""
	@echo "Verify installation:"
	@$(MAKE) verify
	@echo ""
	@echo "Next steps:"
	@echo "  - Run tests: make test-quick"
	@echo "  - Check dist: make check-dist"
	@echo "  - Upload: make upload-test"

dev-setup:  ## Complete development environment setup
	$(PIP) install -e ".[dev,test,lint]"
	$(PIP) install build wheel twine
	@echo "Development environment ready!"

verify:  ## Verify installation
	@echo "=========================================="
	@echo "Installation Verification"
	@echo "=========================================="
	@echo ""
	@echo -n "mlxllm: "
	@$(PYTHON) -c "import mlxllm; print(f'✅ Version {mlxllm.__version__}')" || echo "❌ Import failed"
	@echo -n "metalcutlass: "
	@$(PYTHON) -c "import metalcutlass; print('✅ Installed')" || echo "❌ Import failed"
	@echo -n "mlx: "
	@$(PYTHON) -c "import mlx.core as mx; print(f'✅ Version {mx.__version__}')" || echo "❌ Import failed"
	@echo -n "transformers: "
	@$(PYTHON) -c "import transformers; print(f'✅ Version {transformers.__version__}')" || echo "❌ Import failed"
	@echo -n "torch: "
	@$(PYTHON) -c "import torch; print(f'✅ Version {torch.__version__}')" || echo "❌ Import failed"
	@echo ""
	@echo "Metal GPU:"
	@$(PYTHON) -c "import mlx.core as mx; info = mx.metal.device_info(); print(f'  Device: {info}'); mem = mx.metal.get_active_memory() / 1024**3 if hasattr(mx.metal, 'get_active_memory') else mx.get_active_memory() / 1024**3; print(f'  Active memory: {mem:.2f} GB')" 2>&1 | grep -v deprecated || echo "  ❌ Metal not available"
	@echo ""
	@echo "=========================================="
	@echo "✅ Installation verification complete!"
	@echo "=========================================="

benchmark:  ## Run performance benchmarks
	$(PYTHON) -m pytest $(TEST_DIR) -v -m benchmark --benchmark-only

profile:  ## Profile code with cProfile
	$(PYTHON) -m cProfile -o profile.stats -m pytest $(TEST_DIR)/unit
	@echo "Profile saved to profile.stats"

docs:  ## Build HTML documentation
	$(PYTHON) -m sphinx -b html $(DOCS_SOURCE_DIR) $(DOCS_BUILD_DIR)/html
	@echo "Documentation built in $(DOCS_BUILD_DIR)/html/index.html"

docs-clean:  ## Clean documentation build
	rm -rf $(DOCS_BUILD_DIR)

docs-serve:  ## Serve documentation locally
	$(PYTHON) -m http.server --directory $(DOCS_BUILD_DIR)/html 8000

docs-live:  ## Live rebuild documentation on changes
	$(PYTHON) -m sphinx_autobuild $(DOCS_SOURCE_DIR) $(DOCS_BUILD_DIR)/html

docs-linkcheck:  ## Check documentation links
	$(PYTHON) -m sphinx -b linkcheck $(DOCS_SOURCE_DIR) $(DOCS_BUILD_DIR)/linkcheck

docs-pdf:  ## Build PDF documentation (requires LaTeX)
	$(PYTHON) -m sphinx -b latex $(DOCS_SOURCE_DIR) $(DOCS_BUILD_DIR)/latex
	cd $(DOCS_BUILD_DIR)/latex && make

install-docs:  ## Install documentation dependencies
	$(PIP) install -r docs/requirements.txt

watch-tests:  ## Watch for changes and run tests
	$(PYTHON) -m pytest-watch $(TEST_DIR)

shell:  ## Start interactive Python shell with package imported
	$(PYTHON) -i -c "import mlxllm; from mlxllm import *; print('MLX-LLM imported')"

info:  ## Show package and environment info
	@echo "Python: $(PYTHON)"
	@echo "Package: $(PACKAGE)"
	@$(PYTHON) --version
	@$(PYTHON) -c "import sys; print(f'Python path: {sys.executable}')"
	@$(PYTHON) -c "import mlx; print(f'MLX version: {mlx.__version__}')"
	@echo "Metal device info:"
	@$(PYTHON) -c "import mlx.core as mx; print(mx.metal.device_info())"

# ==============================================
# Environment Management
# ==============================================

ENV_NAME := mlxllm
CONDA_ENV_FILE := environment.yml
VENV_DIR := venv
MIN_PYTHON_VERSION := 3.11
MIN_MACOS_VERSION := 12.0

env-check:  ## Check system requirements and environment status
	@echo "=========================================="
	@echo "MLX-LLM Environment Check"
	@echo "=========================================="
	@echo ""
	@echo "System Requirements:"
	@echo "-------------------"
	@echo -n "macOS Version: "
	@sw_vers -productVersion 2>/dev/null || echo "❌ Cannot detect (not macOS)"
	@echo -n "Architecture: "
	@uname -m | grep -q "arm64" && echo "✅ arm64 (Apple Silicon)" || echo "⚠️  $(shell uname -m) (Intel - limited support)"
	@echo -n "Xcode CLI Tools: "
	@xcode-select -p >/dev/null 2>&1 && echo "✅ Installed" || echo "❌ Not installed (run: xcode-select --install)"
	@echo ""
	@echo "Python Environment:"
	@echo "------------------"
	@echo -n "Python Version: "
	@python3 --version 2>/dev/null || echo "❌ Python 3 not found"
	@echo -n "Python 3.11+: "
	@python3 -c "import sys; exit(0 if sys.version_info >= (3, 11) else 1)" 2>/dev/null && echo "✅ Compatible" || echo "❌ Python 3.11+ required"
	@echo -n "pip: "
	@python3 -m pip --version >/dev/null 2>&1 && echo "✅ Available" || echo "❌ Not found"
	@echo ""
	@echo "Conda/Mamba:"
	@echo "-----------"
	@echo -n "conda: "
	@which conda >/dev/null 2>&1 && echo "✅ $(shell conda --version)" || echo "⚠️  Not found (optional)"
	@echo -n "mamba: "
	@which mamba >/dev/null 2>&1 && echo "✅ $(shell mamba --version)" || echo "⚠️  Not found (optional)"
	@echo -n "mlxllm conda env: "
	@conda env list 2>/dev/null | grep -q "^$(ENV_NAME) " && echo "✅ Exists" || echo "❌ Not found"
	@echo ""
	@echo "Virtual Environment:"
	@echo "-------------------"
	@echo -n "venv directory: "
	@[ -d "$(VENV_DIR)" ] && echo "✅ Exists at $(VENV_DIR)" || echo "❌ Not found"
	@echo ""
	@echo "Current Python:"
	@echo "--------------"
	@which python3 2>/dev/null || echo "❌ Python not in PATH"
	@python3 -c "import sys; print(f'Path: {sys.executable}')" 2>/dev/null || true
	@echo -n "In virtual env: "
	@python3 -c "import sys; exit(0 if sys.prefix != sys.base_prefix else 1)" 2>/dev/null && echo "✅ Yes" || echo "⚠️  No (using system Python)"
	@echo ""
	@echo "MLX-LLM Installation:"
	@echo "--------------------"
	@echo -n "mlxllm: "
	@python3 -c "import mlxllm; print(f'✅ Version {mlxllm.__version__}')" 2>/dev/null || echo "❌ Not installed"
	@echo -n "metalcutlass: "
	@python3 -c "import metalcutlass; print('✅ Installed')" 2>/dev/null || echo "❌ Not installed"
	@echo -n "mlx: "
	@python3 -c "import mlx.core as mx; print(f'✅ Version {mx.__version__}')" 2>/dev/null || echo "❌ Not installed"
	@echo -n "transformers: "
	@python3 -c "import transformers; print(f'✅ Version {transformers.__version__}')" 2>/dev/null || echo "❌ Not installed"
	@echo -n "torch: "
	@python3 -c "import torch; print(f'✅ Version {torch.__version__}')" 2>/dev/null || echo "❌ Not installed"
	@echo ""
	@echo "Metal GPU:"
	@echo "---------"
	@python3 -c "import mlx.core as mx; info = mx.metal.device_info(); print(f'Device: {info}'); mem = mx.metal.get_active_memory() / 1024**3; print(f'Active memory: {mem:.2f} GB')" 2>/dev/null || echo "❌ Metal not available"
	@echo "=========================================="

env-info:  ## Show detailed environment information
	@echo "=========================================="
	@echo "Environment Information"
	@echo "=========================================="
	@echo ""
	@echo "System:"
	@echo "-------"
	@echo "OS: $(shell sw_vers -productName 2>/dev/null || echo 'Unknown') $(shell sw_vers -productVersion 2>/dev/null || echo '')"
	@echo "Kernel: $(shell uname -sr)"
	@echo "Architecture: $(shell uname -m)"
	@echo "CPU: $(shell sysctl -n machdep.cpu.brand_string 2>/dev/null || echo 'Unknown')"
	@echo "CPU Cores: $(shell sysctl -n hw.ncpu 2>/dev/null || echo 'Unknown')"
	@echo "Physical Memory: $(shell sysctl -n hw.memsize 2>/dev/null | awk '{printf "%.1f GB", $$1/1024/1024/1024}' || echo 'Unknown')"
	@echo "GPU Cores: $(shell sysctl -n machdep.gpu.core_count 2>/dev/null || echo 'Unknown')"
	@echo ""
	@echo "Python:"
	@echo "-------"
	@python3 --version
	@echo "Executable: $(shell which python3)"
	@python3 -c "import sys; print(f'Prefix: {sys.prefix}')"
	@python3 -c "import sys; print(f'Base prefix: {sys.base_prefix}')"
	@python3 -c "import sys; print(f'In virtualenv: {sys.prefix != sys.base_prefix}')"
	@echo ""
	@echo "Environment Variables:"
	@echo "---------------------"
	@echo "VIRTUAL_ENV: $${VIRTUAL_ENV:-Not set}"
	@echo "CONDA_DEFAULT_ENV: $${CONDA_DEFAULT_ENV:-Not set}"
	@echo "PATH (first 3 entries):"
	@echo "$${PATH}" | tr ':' '\n' | head -3 | sed 's/^/  /'
	@echo ""
	@echo "Installed Packages (key dependencies):"
	@echo "--------------------------------------"
	@python3 -m pip list 2>/dev/null | grep -E "(mlxllm|metalcutlass|mlx|torch|transformers|numpy)" || echo "Cannot list packages"
	@echo "=========================================="

env-create-conda:  ## Create conda environment from environment.yml
	@echo "Creating conda environment: $(ENV_NAME)"
	@if ! which conda >/dev/null 2>&1 && ! which mamba >/dev/null 2>&1; then \
		echo "❌ Error: Neither conda nor mamba found. Install Miniconda or Miniforge first."; \
		echo "   Download from: https://github.com/conda-forge/miniforge/releases"; \
		exit 1; \
	fi
	@if [ ! -f "$(CONDA_ENV_FILE)" ]; then \
		echo "❌ Error: $(CONDA_ENV_FILE) not found"; \
		exit 1; \
	fi
	@if conda env list | grep -q "^$(ENV_NAME) "; then \
		echo "⚠️  Warning: Environment '$(ENV_NAME)' already exists"; \
		read -p "Remove and recreate? (y/N): " confirm; \
		if [ "$$confirm" = "y" ]; then \
			conda env remove -n $(ENV_NAME) -y; \
		else \
			echo "Aborted. Use 'conda activate $(ENV_NAME)' to use existing environment."; \
			exit 1; \
		fi \
	fi
	@if which mamba >/dev/null 2>&1; then \
		echo "Using mamba (faster)..."; \
		mamba env create -f $(CONDA_ENV_FILE); \
	else \
		echo "Using conda..."; \
		conda env create -f $(CONDA_ENV_FILE); \
	fi
	@echo "✅ Conda environment '$(ENV_NAME)' created successfully"
	@echo ""
	@echo "To activate, run:"
	@echo "  conda activate $(ENV_NAME)"

env-create-venv:  ## Create Python virtual environment
	@echo "Creating Python virtual environment: $(VENV_DIR)"
	@python3 -c "import sys; exit(0 if sys.version_info >= (3, 11) else 1)" || (echo "❌ Error: Python 3.11+ required"; exit 1)
	@if [ -d "$(VENV_DIR)" ]; then \
		echo "⚠️  Warning: Virtual environment '$(VENV_DIR)' already exists"; \
		read -p "Remove and recreate? (y/N): " confirm; \
		if [ "$$confirm" = "y" ]; then \
			rm -rf $(VENV_DIR); \
		else \
			echo "Aborted. Use 'source $(VENV_DIR)/bin/activate' to use existing environment."; \
			exit 1; \
		fi \
	fi
	@python3 -m venv $(VENV_DIR)
	@$(VENV_DIR)/bin/pip install --upgrade pip setuptools wheel
	@echo "✅ Virtual environment '$(VENV_DIR)' created successfully"
	@echo ""
	@echo "To activate, run:"
	@echo "  source $(VENV_DIR)/bin/activate"

env-activate-help:  ## Show how to activate environments
	@echo "=========================================="
	@echo "Environment Activation"
	@echo "=========================================="
	@echo ""
	@echo "Conda Environment:"
	@echo "-----------------"
	@if conda env list 2>/dev/null | grep -q "^$(ENV_NAME) "; then \
		echo "Environment '$(ENV_NAME)' is installed."; \
		echo ""; \
		echo "To activate:"; \
		echo "  conda activate $(ENV_NAME)"; \
		echo ""; \
		echo "To deactivate:"; \
		echo "  conda deactivate"; \
	else \
		echo "Environment '$(ENV_NAME)' not found."; \
		echo "Create it with: make env-create-conda"; \
	fi
	@echo ""
	@echo "Virtual Environment:"
	@echo "-------------------"
	@if [ -d "$(VENV_DIR)" ]; then \
		echo "Virtual environment '$(VENV_DIR)' exists."; \
		echo ""; \
		echo "To activate (bash/zsh):"; \
		echo "  source $(VENV_DIR)/bin/activate"; \
		echo ""; \
		echo "To activate (fish):"; \
		echo "  source $(VENV_DIR)/bin/activate.fish"; \
		echo ""; \
		echo "To deactivate:"; \
		echo "  deactivate"; \
	else \
		echo "Virtual environment '$(VENV_DIR)' not found."; \
		echo "Create it with: make env-create-venv"; \
	fi
	@echo ""
	@echo "Current Status:"
	@echo "--------------"
	@if [ -n "$$CONDA_DEFAULT_ENV" ]; then \
		echo "Active conda env: $$CONDA_DEFAULT_ENV"; \
	elif [ -n "$$VIRTUAL_ENV" ]; then \
		echo "Active virtual env: $$VIRTUAL_ENV"; \
	else \
		echo "⚠️  No environment activated (using system Python)"; \
	fi
	@echo "=========================================="

env-install-prod:  ## Install production dependencies only
	@echo "Installing production dependencies..."
	@if [ ! -f "requirements/requirements.txt" ]; then \
		echo "❌ Error: requirements/requirements.txt not found"; \
		exit 1; \
	fi
	@python3 -m pip install --upgrade pip
	@python3 -m pip install -r requirements/requirements.txt
	@echo "✅ Production dependencies installed"

env-install-dev:  ## Install development dependencies
	@echo "Installing development dependencies..."
	@if [ ! -f "requirements/requirements.dev.txt" ]; then \
		echo "❌ Error: requirements/requirements.dev.txt not found"; \
		exit 1; \
	fi
	@python3 -m pip install --upgrade pip
	@python3 -m pip install -r requirements/requirements.dev.txt
	@echo "✅ Development dependencies installed"

env-install-all:  ## Install all dependencies (prod + dev + docs)
	@echo "Installing all dependencies..."
	@python3 -m pip install --upgrade pip
	@if [ -f "requirements/requirements.txt" ]; then \
		python3 -m pip install -r requirements/requirements.txt; \
	fi
	@if [ -f "requirements/requirements.dev.txt" ]; then \
		python3 -m pip install -r requirements/requirements.dev.txt; \
	fi
	@if [ -f "requirements/requirements.docs.txt" ]; then \
		python3 -m pip install -r requirements/requirements.docs.txt; \
	fi
	@echo "✅ All dependencies installed"

env-install-packages:  ## Install mlxllm and metalcutlass packages
	@echo "=========================================="
	@echo "Installing MLX-LLM Packages"
	@echo "=========================================="
	@echo ""
	@echo "Step 1/2: Installing metalcutlass..."
	@if [ ! -d "packages/metalcutlass" ]; then \
		echo "❌ Error: packages/metalcutlass directory not found"; \
		exit 1; \
	fi
	@cd packages/metalcutlass && python3 -m pip install --no-build-isolation -e .
	@echo "✅ metalcutlass installed"
	@echo ""
	@echo "Step 2/2: Installing mlxllm..."
	@python3 -m pip install -e .
	@echo "✅ mlxllm installed"
	@echo ""
	@echo "=========================================="
	@echo "Installation complete!"
	@echo "=========================================="
	@echo ""
	@echo "Verify installation:"
	@python3 -c "import mlxllm; print(f'  mlxllm: {mlxllm.__version__}')" || echo "  ❌ mlxllm import failed"
	@python3 -c "import metalcutlass; print('  metalcutlass: OK')" || echo "  ❌ metalcutlass import failed"
	@python3 -c "import mlx.core as mx; print(f'  mlx: {mx.__version__}')" || echo "  ❌ mlx import failed"

env-install-packages-dev:  ## Install mlxllm and metalcutlass with dev dependencies
	@echo "=========================================="
	@echo "Installing MLX-LLM Packages (Development)"
	@echo "=========================================="
	@echo ""
	@echo "Step 1/2: Installing metalcutlass..."
	@if [ ! -d "packages/metalcutlass" ]; then \
		echo "❌ Error: packages/metalcutlass directory not found"; \
		exit 1; \
	fi
	@cd packages/metalcutlass && python3 -m pip install --no-build-isolation -e .
	@echo "✅ metalcutlass installed"
	@echo ""
	@echo "Step 2/2: Installing mlxllm with dev dependencies..."
	@python3 -m pip install -e ".[dev]"
	@echo "✅ mlxllm installed with dev dependencies"
	@echo ""
	@echo "=========================================="
	@echo "Installation complete!"
	@echo "=========================================="
	@echo ""
	@echo "Verify installation:"
	@python3 -c "import mlxllm; print(f'  mlxllm: {mlxllm.__version__}')" || echo "  ❌ mlxllm import failed"
	@python3 -c "import metalcutlass; print('  metalcutlass: OK')" || echo "  ❌ metalcutlass import failed"
	@python3 -c "import mlx.core as mx; print(f'  mlx: {mx.__version__}')" || echo "  ❌ mlx import failed"
	@python3 -c "import pytest; print(f'  pytest: {pytest.__version__}')" || echo "  ⚠️  pytest not installed"

env-setup-complete:  ## Complete environment setup (check, install deps, install mlxllm)
	@echo "=========================================="
	@echo "Complete Environment Setup"
	@echo "=========================================="
	@echo ""
	@echo "Step 1/4: Checking environment..."
	@$(MAKE) env-check
	@echo ""
	@echo "Step 2/4: Installing all dependencies..."
	@$(MAKE) env-install-all
	@echo ""
	@echo "Step 3/4: Installing metalcutlass..."
	@cd packages/metalcutlass && python3 -m pip install --no-build-isolation -e .
	@echo ""
	@echo "Step 4/4: Installing mlxllm..."
	@python3 -m pip install -e ".[dev]"
	@echo ""
	@echo "=========================================="
	@echo "✅ Environment setup complete!"
	@echo "=========================================="
	@echo ""
	@echo "Verify installation:"
	@$(MAKE) verify
	@echo ""
	@echo "Run tests:"
	@echo "  make test-quick"
	@echo ""

env-clean:  ## Clean virtual environment (keeps conda env)
	@echo "Cleaning virtual environment..."
	@if [ -d "$(VENV_DIR)" ]; then \
		echo "Removing $(VENV_DIR)..."; \
		rm -rf $(VENV_DIR); \
		echo "✅ Virtual environment removed"; \
	else \
		echo "No virtual environment found at $(VENV_DIR)"; \
	fi

env-reset:  ## Reset environment (remove venv, uninstall packages)
	@echo "=========================================="
	@echo "Environment Reset"
	@echo "=========================================="
	@echo ""
	@echo "⚠️  WARNING: This will:"
	@echo "  - Remove virtual environment (if exists)"
	@echo "  - Uninstall mlxllm and metalcutlass"
	@echo "  - Keep conda environment (remove manually if needed)"
	@echo ""
	@read -p "Continue? (y/N): " confirm; \
	if [ "$$confirm" != "y" ]; then \
		echo "Aborted."; \
		exit 1; \
	fi
	@echo ""
	@echo "Uninstalling packages..."
	@python3 -m pip uninstall mlxllm metalcutlass -y 2>/dev/null || true
	@echo ""
	@echo "Removing virtual environment..."
	@$(MAKE) env-clean
	@echo ""
	@echo "✅ Environment reset complete"
	@echo ""
	@echo "To remove conda environment manually:"
	@echo "  conda env remove -n $(ENV_NAME) -y"

requirements-show:  ## Show parsed requirements from requirements files
	$(PYTHON) scripts/parse_requirements.py

requirements-freeze:  ## Freeze current environment to requirements files
	$(PYTHON) -m pip freeze > requirements/requirements.frozen.txt
	@echo "Frozen requirements saved to requirements/requirements.frozen.txt"

requirements-check:  ## Check if pyproject.toml and requirements files are in sync
	$(PYTHON) scripts/sync_requirements.py --check

requirements-sync-to-files:  ## Update requirements files from pyproject.toml
	$(PYTHON) scripts/sync_requirements.py --to-files

requirements-sync-to-toml:  ## Update pyproject.toml from requirements files
	$(PYTHON) scripts/sync_requirements.py --to-toml

# ==============================================
# CMake Build System Integration
# ==============================================

cmake-check:  ## Check CMake availability and dependencies
	@echo "=========================================="
	@echo "CMake Environment Check"
	@echo "=========================================="
	@echo ""
	@echo "Build Tools:"
	@echo "-----------"
	@echo -n "CMake: "
	@which cmake >/dev/null 2>&1 && cmake --version | head -1 || echo "❌ Not found (install with: brew install cmake)"
	@echo -n "Make: "
	@which make >/dev/null 2>&1 && make --version | head -1 || echo "❌ Not found"
	@echo -n "C++ Compiler: "
	@which clang++ >/dev/null 2>&1 && clang++ --version | head -1 || echo "❌ Not found (install Xcode CLI Tools)"
	@echo ""
	@echo "Python Development:"
	@echo "------------------"
	@echo -n "Python: "
	@$(PYTHON) --version 2>/dev/null || echo "❌ Python not found"
	@echo "Executable: $(PYTHON)"
	@echo -n "Python headers: "
	@$(PYTHON) -c "import sysconfig; print(f'✅ {sysconfig.get_path(\"include\")}');" 2>/dev/null || echo "❌ Not found"
	@echo ""
	@echo "Python Packages:"
	@echo "---------------"
	@echo -n "numpy: "
	@$(PYTHON) -c "import numpy; print(f'✅ {numpy.__version__} (include: {numpy.get_include()})');" 2>/dev/null || echo "❌ Not installed (run: pip install numpy)"
	@echo -n "mlx: "
	@$(PYTHON) -c "import mlx.core as mx; print(f'✅ {mx.__version__}');" 2>/dev/null || echo "❌ Not installed (run: pip install mlx)"
	@echo -n "torch: "
	@$(PYTHON) -c "import torch; print(f'✅ {torch.__version__}');" 2>/dev/null || echo "⚠️  Not installed (optional)"
	@echo ""
	@echo "Optional Dependencies:"
	@echo "--------------------"
	@echo -n "metalcutlass: "
	@$(PYTHON) -c "import metalcutlass; print(f'✅ Installed');" 2>/dev/null || echo "⚠️  Not installed (build with: cd packages/metalcutlass && pip install -e .)"
	@echo -n "DNNL: "
	@[ -f "/usr/local/lib/libdnnl.dylib" ] && echo "✅ Found in /usr/local/lib" || echo "⚠️  Not found (optional, for CPU backend)"
	@echo ""
	@echo "CMake Configuration:"
	@echo "------------------"
	@echo "Build directory: $(CMAKE_BUILD_DIR)"
	@if [ -d "$(CMAKE_BUILD_DIR)" ]; then \
		echo "Status: ✅ Configured"; \
		echo "Build type: $$(grep CMAKE_BUILD_TYPE $(CMAKE_BUILD_DIR)/CMakeCache.txt 2>/dev/null | cut -d= -f2 || echo 'Unknown')"; \
	else \
		echo "Status: ❌ Not configured (run: make cmake-setup)"; \
	fi
	@echo "Install prefix: $(CMAKE_INSTALL_PREFIX)"
	@echo "Source directory: $(CSRC_DIR)"
	@echo ""
	@echo "System Info:"
	@echo "-----------"
	@echo "Architecture: $$(uname -m)"
	@echo "macOS: $$(sw_vers -productVersion 2>/dev/null || echo 'Unknown')"
	@echo "CPU: $$(sysctl -n machdep.cpu.brand_string 2>/dev/null || echo 'Unknown')"
	@echo "CPU Cores: $$(sysctl -n hw.ncpu 2>/dev/null || echo 'Unknown')"
	@echo "=========================================="

cmake-setup:  ## Setup CMake (check dependencies and configure)
	@echo "=========================================="
	@echo "CMake Setup"
	@echo "=========================================="
	@echo ""
	@echo "Step 1/4: Checking dependencies..."
	@echo ""
	@$(MAKE) cmake-check
	@echo ""
	@echo "Step 2/4: Verifying requirements..."
	@which cmake >/dev/null 2>&1 || (echo "❌ Error: CMake not found. Install with: brew install cmake"; exit 1)
	@which clang++ >/dev/null 2>&1 || (echo "❌ Error: C++ compiler not found. Install Xcode CLI Tools: xcode-select --install"; exit 1)
	@$(PYTHON) -c "import numpy" 2>/dev/null || (echo "❌ Error: numpy not found. Install with: pip install numpy"; exit 1)
	@echo "✅ All requirements satisfied"
	@echo ""
	@echo "Step 3/4: Configuring CMake..."
	@if [ -d "$(CMAKE_BUILD_DIR)" ]; then \
		echo "⚠️  CMake already configured at $(CMAKE_BUILD_DIR)"; \
		read -p "Reconfigure? (y/N): " confirm; \
		if [ "$$confirm" = "y" ]; then \
			rm -rf $(CMAKE_BUILD_DIR); \
			$(MAKE) cmake-configure; \
		else \
			echo "Keeping existing configuration."; \
		fi \
	else \
		$(MAKE) cmake-configure; \
	fi
	@echo ""
	@echo "Step 4/4: Verifying configuration..."
	@if [ -f "$(CMAKE_BUILD_DIR)/CMakeCache.txt" ]; then \
		echo "✅ CMake configured successfully"; \
		echo ""; \
		echo "Configuration details:"; \
		echo "  Build type: $$(grep CMAKE_BUILD_TYPE $(CMAKE_BUILD_DIR)/CMakeCache.txt | cut -d= -f2)"; \
		echo "  Install prefix: $$(grep CMAKE_INSTALL_PREFIX:PATH $(CMAKE_BUILD_DIR)/CMakeCache.txt | cut -d= -f2)"; \
		echo "  Python: $$(grep Python3_EXECUTABLE:FILEPATH $(CMAKE_BUILD_DIR)/CMakeCache.txt | cut -d= -f2)"; \
	else \
		echo "❌ CMake configuration failed"; \
		exit 1; \
	fi
	@echo ""
	@echo "=========================================="
	@echo "✅ CMake setup complete!"
	@echo "=========================================="
	@echo ""
	@echo "Next steps:"
	@echo "  - Build extensions: make cmake-build"
	@echo "  - Install extensions: make cmake-install"
	@echo "  - Or do both: make cmake-all"

cmake-configure:  ## Configure CMake build system
	@echo "Configuring CMake build system..."
	@mkdir -p $(CMAKE_BUILD_DIR)
	cd $(CMAKE_BUILD_DIR) && $(CMAKE) \
		-DCMAKE_BUILD_TYPE=Release \
		-DCMAKE_INSTALL_PREFIX=$(CMAKE_INSTALL_PREFIX) \
		-DPython3_EXECUTABLE=$(PYTHON) \
		-DPython3_ROOT_DIR=/Users/ryanoboyle/miniforge3/envs/mlxllm \
		-DPYTHON_EXECUTABLE=$(PYTHON) \
		-DCMAKE_PREFIX_PATH=/Users/ryanoboyle/miniforge3/envs/mlxllm \
		-DBUILD_PYTHON_EXTENSIONS=ON \
		-DBUILD_TESTS=OFF \
		../../$(CSRC_DIR)
	@echo "CMake configuration complete"

cmake-build:  ## Build C++ extensions using CMake
	@echo "Building C++ extensions with CMake..."
	@if [ ! -d "$(CMAKE_BUILD_DIR)" ]; then \
		echo "CMake not configured. Run 'make cmake-configure' first."; \
		exit 1; \
	fi
	cd $(CMAKE_BUILD_DIR) && $(CMAKE) --build . --config Release
	@echo "CMake build complete"

cmake-install:  ## Install C++ extensions built with CMake
	@echo "Installing C++ extensions..."
	@if [ ! -d "$(CMAKE_BUILD_DIR)" ]; then \
		echo "CMake not configured. Run 'make cmake-configure' first."; \
		exit 1; \
	fi
	cd $(CMAKE_BUILD_DIR) && $(CMAKE) --install .
	@echo "Installation complete"

cmake-clean:  ## Clean CMake build artifacts
	@echo "Cleaning CMake build artifacts..."
	rm -rf $(CMAKE_BUILD_DIR)
	@echo "CMake build cleaned"

cmake-rebuild: cmake-clean cmake-configure cmake-build  ## Clean, configure, and build with CMake

cmake-all: cmake-configure cmake-build cmake-install  ## Full CMake build and install

cmake-info:  ## Show CMake configuration and system info
	@echo "=========================================="
	@echo "CMake Build System Information"
	@echo "=========================================="
	@echo "CMake: $(CMAKE)"
	@echo "Build directory: $(CMAKE_BUILD_DIR)"
	@echo "Install prefix: $(CMAKE_INSTALL_PREFIX)"
	@echo "Source directory: $(CSRC_DIR)"
	@echo "Python: $(PYTHON)"
	@echo ""
	@echo "Available CMake modules:"
	@echo "  - cmake/utils.cmake: Utility functions for MLX/Metal builds"
	@echo "  - cmake/extension.cmake: Python extension module builders"
	@echo "  - cmake/metalcutlass.cmake: MetalCutlass integration"
	@echo "  - cmake/m4max.cmake: M4 Max/Pro specific optimizations"
	@echo ""
	@echo "System detection:"
	@uname -m | grep -q "arm64" && echo "  - Architecture: ARM64 (Apple Silicon)" || echo "  - Architecture: $(shell uname -m)"
	@sw_vers -productVersion 2>/dev/null && echo "  - macOS: $(shell sw_vers -productVersion)" || true
	@sysctl -n machdep.cpu.brand_string 2>/dev/null | grep -q "Apple M4" && echo "  - M4 chip detected" || echo "  - Not M4 chip"
	@echo "=========================================="

cmake-detect-m4:  ## Detect M4 chip and show optimization info
	@echo "Detecting M4 chip configuration..."
	@sysctl -n machdep.cpu.brand_string 2>/dev/null || echo "Cannot detect CPU"
	@echo ""
	@echo "Performance cores:"
	@sysctl -n hw.perflevel1.physicalcpu 2>/dev/null || echo "N/A"
	@echo "Efficiency cores:"
	@sysctl -n hw.perflevel0.physicalcpu 2>/dev/null || echo "N/A"
	@echo "Total CPUs:"
	@sysctl -n hw.ncpu 2>/dev/null || echo "N/A"
	@echo ""
	@echo "Memory:"
	@$(PYTHON) -c "import subprocess; mem = int(subprocess.check_output(['sysctl', '-n', 'hw.memsize']).strip()) / (1024**3); print(f'{mem:.1f} GB')" 2>/dev/null || echo "N/A"
	@echo ""
	@echo "GPU cores:"
	@sysctl -n machdep.gpu.core_count 2>/dev/null || echo "N/A"

cmake-extensions:  ## List available C++ extension modules
	@echo "Available C++ Extensions:"
	@echo "  - all2all: All-to-all communication kernels"
	@echo "  - cpu: CPU backend operations (with optional DNNL)"
	@echo "  - moe: Mixture-of-Experts kernels"
	@echo "  - attention: Attention mechanism kernels"
	@echo "  - core: Core utility operations"
	@echo "  - metalcutlass: MetalCutlass integration (requires metalcutlass package)"
	@echo ""
	@echo "Metal shader files are automatically included from:"
	@echo "  - csrc/**/*.metal"
	@echo ""
	@echo "To build extensions, use: make cmake-all"

cmake-test-build:  ## Test CMake build without installation
	@echo "Testing CMake build configuration..."
	@mkdir -p $(CMAKE_BUILD_DIR)
	cd $(CMAKE_BUILD_DIR) && $(CMAKE) \
		-DCMAKE_BUILD_TYPE=Debug \
		-DCMAKE_VERBOSE_MAKEFILE=ON \
		-DPython3_EXECUTABLE=$(PYTHON) \
		../../$(CSRC_DIR) && \
	$(CMAKE) --build . --config Debug --verbose
	@echo "Test build complete"

cmake-check-deps:  ## Check CMake build dependencies
	@echo "Checking CMake build dependencies..."
	@echo ""
	@echo "CMake:"
	@which cmake > /dev/null 2>&1 && cmake --version | head -1 || echo "  ❌ CMake not found"
	@echo ""
	@echo "Python development headers:"
	@$(PYTHON) -c "import sysconfig; print(f'  ✓ Found: {sysconfig.get_path(\"include\")}');" 2>/dev/null || echo "  ❌ Not found"
	@echo ""
	@echo "NumPy:"
	@$(PYTHON) -c "import numpy; print(f'  ✓ Version {numpy.__version__}: {numpy.get_include()}');" 2>/dev/null || echo "  ❌ NumPy not installed"
	@echo ""
	@echo "MLX:"
	@$(PYTHON) -c "import mlx.core as mx; print(f'  ✓ Version {mx.__version__}');" 2>/dev/null || echo "  ❌ MLX not installed"
	@echo ""
	@echo "MetalCutlass (optional):"
	@$(PYTHON) -c "import metalcutlass; print(f'  ✓ Found: {metalcutlass.__file__}');" 2>/dev/null || echo "  ℹ Not installed (optional)"
	@echo ""
	@echo "DNNL (optional):"
	@[ -f "/usr/local/lib/libdnnl.dylib" ] && echo "  ✓ Found in /usr/local/lib" || echo "  ℹ Not found (optional)"

cmake-metalcutlass:  ## Build MetalCutlass extensions with CMake
	@echo "Building MetalCutlass extensions..."
	@$(PYTHON) -c "import metalcutlass" 2>/dev/null || (echo "Error: MetalCutlass not installed. Install with: cd packages/metalcutlass && pip install -e ."; exit 1)
	@mkdir -p $(CMAKE_BUILD_DIR)
	cd $(CMAKE_BUILD_DIR) && $(CMAKE) \
		-DCMAKE_BUILD_TYPE=Release \
		-DCMAKE_INSTALL_PREFIX=$(CMAKE_INSTALL_PREFIX) \
		-DPython3_EXECUTABLE=$(PYTHON) \
		-DBUILD_METALCUTLASS=ON \
		../../$(CSRC_DIR) && \
	$(CMAKE) --build . --target _metalcutlass_ops --config Release
	@echo "MetalCutlass extension built"

# ==============================================
# Docker Commands
# ==============================================

DOCKER_COMPOSE := docker-compose
DOCKER := docker
PROD_SERVICE := mlxllm
DEV_SERVICE := mlxllm-dev
TEST_SERVICE := mlxllm-test

docker-build:  ## Build production Docker image
	@echo "Building production Docker image..."
	$(DOCKER_COMPOSE) build $(PROD_SERVICE)
	@echo "Production image built successfully"

docker-build-dev:  ## Build development Docker image
	@echo "Building development Docker image..."
	$(DOCKER_COMPOSE) build $(DEV_SERVICE)
	@echo "Development image built successfully"

docker-build-all:  ## Build all Docker images (production, dev, test)
	@echo "Building all Docker images..."
	$(DOCKER_COMPOSE) build
	@echo "All images built successfully"

docker-up:  ## Start production service in detached mode
	@echo "Starting production service..."
	$(DOCKER_COMPOSE) up -d $(PROD_SERVICE)
	@echo "Production service started. View logs with: make docker-logs"

docker-up-dev:  ## Start development service in interactive mode
	@echo "Starting development service..."
	$(DOCKER_COMPOSE) up $(DEV_SERVICE)

docker-down:  ## Stop and remove all containers
	@echo "Stopping all services..."
	$(DOCKER_COMPOSE) down
	@echo "All services stopped"

docker-restart:  ## Restart production service
	@echo "Restarting production service..."
	$(DOCKER_COMPOSE) restart $(PROD_SERVICE)
	@echo "Production service restarted"

docker-restart-dev:  ## Restart development service
	@echo "Restarting development service..."
	$(DOCKER_COMPOSE) restart $(DEV_SERVICE)
	@echo "Development service restarted"

docker-logs:  ## Show production service logs
	$(DOCKER_COMPOSE) logs -f $(PROD_SERVICE)

docker-logs-dev:  ## Show development service logs
	$(DOCKER_COMPOSE) logs -f $(DEV_SERVICE)

docker-logs-test:  ## Show test service logs
	$(DOCKER_COMPOSE) logs -f $(TEST_SERVICE)

docker-shell:  ## Open shell in production container
	@echo "Opening shell in production container..."
	$(DOCKER_COMPOSE) exec $(PROD_SERVICE) /bin/bash

docker-shell-dev:  ## Open shell in development container
	@echo "Opening shell in development container..."
	$(DOCKER_COMPOSE) exec $(DEV_SERVICE) /bin/bash

docker-test:  ## Run tests in test container
	@echo "Running tests in container..."
	$(DOCKER_COMPOSE) up --abort-on-container-exit $(TEST_SERVICE)

docker-test-run:  ## Run tests in running dev container
	@echo "Running tests in development container..."
	$(DOCKER_COMPOSE) exec $(DEV_SERVICE) pytest -m "not slow and not requires_metal" tests/unit/

docker-clean:  ## Remove all containers and volumes
	@echo "Cleaning up containers and volumes..."
	$(DOCKER_COMPOSE) down -v
	@echo "Containers and volumes removed"

docker-prune:  ## Remove all unused Docker resources (CAUTION!)
	@echo "WARNING: This will remove all unused Docker images, containers, and volumes!"
	@read -p "Are you sure? (y/N): " confirm && [ "$$confirm" = "y" ] || exit 1
	$(DOCKER) system prune -af --volumes
	@echo "Docker cleanup complete"

docker-info:  ## Show Docker container status and info
	@echo "=========================================="
	@echo "Docker Service Status"
	@echo "=========================================="
	@echo ""
	@echo "Running containers:"
	@$(DOCKER_COMPOSE) ps
	@echo ""
	@echo "Docker images:"
	@$(DOCKER) images | grep mlxllm || echo "No mlxllm images found"
	@echo ""
	@echo "Volume usage:"
	@$(DOCKER) volume ls | grep mlxllm || echo "No mlxllm volumes found"
	@echo "=========================================="

docker-rebuild:  ## Rebuild and restart production service
	@echo "Rebuilding and restarting production service..."
	$(DOCKER_COMPOSE) up -d --build $(PROD_SERVICE)
	@echo "Production service rebuilt and restarted"

docker-rebuild-dev:  ## Rebuild and restart development service
	@echo "Rebuilding and restarting development service..."
	$(DOCKER_COMPOSE) up -d --build $(DEV_SERVICE)
	@echo "Development service rebuilt and restarted"

docker-stop:  ## Stop all services without removing containers
	@echo "Stopping all services..."
	$(DOCKER_COMPOSE) stop
	@echo "All services stopped"

docker-start:  ## Start all previously created containers
	@echo "Starting all services..."
	$(DOCKER_COMPOSE) start
	@echo "All services started"

docker-ps:  ## Show status of Docker containers
	$(DOCKER_COMPOSE) ps

docker-pull:  ## Pull latest base images for rebuilding
	@echo "Pulling latest base images..."
	$(DOCKER_COMPOSE) pull
	@echo "Base images updated"

# Convenience aliases
t: test  ## Alias for test
tu: test-unit  ## Alias for test-unit
ti: test-integration  ## Alias for test-integration
l: lint  ## Alias for lint
f: format  ## Alias for format
c: clean  ## Alias for clean
b: build  ## Alias for build
