# =============================================================================
# CrystFlux Makefile - CI-first design with script integration
# =============================================================================

# Environment variables (CI=1 for automated pipelines)
# CI environment detection (1, true, True, TRUE = CI mode)
CI ?= 0
# ANSI colors: 1=terminal (local), 0=plain text (CI)
ANSI_COLOR = $(if $(filter 1 true True TRUE,$(CI)),0,1)
MYPY_STRICT ?= 0
MYPY_OPTS = $(if $(filter 1,$(MYPY_STRICT)),--warn-unused-ignores --warn-return-any --check-untyped-defs,)

# =============================================================================
# .PHONY Targets - Conceptual Execution Contracts
# =============================================================================
# In this modern Python context, the Makefile evolves from a "file build system"
# into a "task runner." .PHONY targets represent abstract procedures and 
# conceptual contracts rather than physical artifacts. These declarations 
# ensure execution remains deterministic regardless of the local file state.

# 1. Meta & Discovery
.PHONY: help clean docs

# 2. High-level Orchestration (Entry Points)
.PHONY: verify check-static check-static-examples

# 3. Execution-based Analysis
.PHONY: test coverage

# 4. Static Analysis Primitives (Main: src, tests)
.PHONY: deps-gate lint ruff typecheck pyright mypy mypy-stubs

# 5. Static Analysis Primitives (Extended: including examples)
.PHONY: lint-examples ruff-examples typecheck-examples \
        pyright-examples mypy-examples

# 6. Environment & Provisioning
.PHONY: install install-dev install-numpy install-pydantic install-all

# 7. Distribution & CI/CD Pipeline
.PHONY: build ci-install lint-lock ci ci-release

# 8. Legacy Shims (Backward Compatibility)
.PHONY: check

# =============================================================================
# Directory configuration
# =============================================================================
# Core directories (always checked)
MAIN_DIRS   = src tests

# Extended directories (optional, for examples)
ALL_DIRS    = src tests examples

# =============================================================================
# Cleanup configuration (Strictly tool-generated artifacts)
# =============================================================================
# Tier 1: Internal tool caches (Safe to delete, auto-regenerated)
CLEAN_CACHES   = .mypy_cache .ruff_cache .pytest_cache .pyrightcache .basedpyrightcache

# Tier 2: Test & Coverage reports
CLEAN_REPORTS  = .coverage htmlcov

# Tier 3: Build & Distribution artifacts
CLEAN_BUILD    = build dist *.egg-info

# Tier 4: Generated documentation
CLEAN_DOCS     = .docs

# Note: The following are EXCLUDED from clean to protect developer work:
# - .venv/ (Delete manually if a fresh environment is needed)
# - drafts/, sandbox/, tmp/, src/legacy/ (Developer assets)
# - AGENTS.md, GEMINI.md, etc. (Project context)

# =============================================================================
# Color and output configuration
# =============================================================================
ifeq ($(ANSI_COLOR),1)
  COLOR_GREEN  := \033[0;32m
  COLOR_YELLOW := \033[0;33m
  COLOR_RED    := \033[0;31m
  COLOR_RESET  := \033[0m
  ECHO_INFO    := @printf "$(COLOR_GREEN)[INFO]$(COLOR_RESET) %s\n"
  ECHO_DONE    := @printf "$(COLOR_GREEN)✓ Done$(COLOR_RESET)\n"
else
  ECHO_INFO    := @printf "[INFO] %s\n"
  ECHO_DONE    := @printf "Done\n"
endif

# Test verbosity: CI uses quiet mode
TEST_ARGS   = $(if $(filter 1,$(CI)),-q,--tb=short)
COV_ARGS    = --cov=crystflux --cov-report=term-missing

# =============================================================================
# Dependency Gate (triadic structure enforcement)
# =============================================================================
deps-gate:
	$(ECHO_INFO) "Checking dependency gate..."
	@uv run python scripts/check_deps.py
	$(ECHO_DONE)

# =============================================================================
# Linting
# =============================================================================
lint: ruff

ruff:
	$(ECHO_INFO) "Running ruff on main (src, tests)..."
	@uv run ruff check $(MAIN_DIRS)
	$(ECHO_DONE)

# Examples linting
lint-examples: ruff-examples

ruff-examples:
	$(ECHO_INFO) "Running ruff on all (including examples)..."
	@uv run ruff check $(ALL_DIRS)
	$(ECHO_DONE)

# =============================================================================
# Type Checking
# =============================================================================
typecheck: pyright mypy

pyright:
	$(ECHO_INFO) "Running basedpyright on main (src, tests)..."
	@uv run basedpyright $(MAIN_DIRS)
	$(ECHO_DONE)

mypy:
	$(ECHO_INFO) "Running mypy on main (src, tests)..."
	@uv run mypy $(MYPY_OPTS) $(MAIN_DIRS)
	$(ECHO_DONE)

# Examples type checking
typecheck-examples: pyright-examples mypy-examples

pyright-examples:
	$(ECHO_INFO) "Running basedpyright on all (including examples)..."
	@uv run basedpyright $(ALL_DIRS)
	$(ECHO_DONE)

mypy-examples:
	$(ECHO_INFO) "Running mypy on all (including examples)..."
	@uv run mypy $(MYPY_OPTS) $(ALL_DIRS)
	$(ECHO_DONE)

mypy-stubs:
	$(ECHO_INFO) "Checking stub consistency for crystflux.v1..."
	@uv run mypy --explicit-package-bases --check-untyped-defs -p crystflux.v1
	$(ECHO_DONE)

# =============================================================================
# Main Check Targets
# =============================================================================
# check-static: Static analysis (lint + typecheck)
check-static: deps-gate lint typecheck
	$(ECHO_INFO) "Static analysis passed!"

# check: Legacy alias for check-static (backward compatibility, kept until v0.30)
check: check-static

# check-static-examples: Static analysis including examples
check-static-examples: deps-gate lint-examples typecheck-examples
	$(ECHO_INFO) "Static analysis (with examples) passed!"

# verify: Complete verification (static + test)
verify: check-static test
	$(ECHO_INFO) "Verification complete!"

# =============================================================================
# Testing
# =============================================================================
test:
	$(ECHO_INFO) "Running pytest..."
	@uv run pytest tests $(TEST_ARGS)
	$(ECHO_DONE)

coverage:
	$(ECHO_INFO) "Running pytest with coverage..."
	@uv run pytest tests $(TEST_ARGS) $(COV_ARGS)
	$(ECHO_DONE)

# =============================================================================
# Installation
# =============================================================================
install: install-dev

install-dev:
	$(ECHO_INFO) "Installing crystflux with dev dependencies..."
	@uv pip install -e ".[dev]"

install-numpy:
	$(ECHO_INFO) "Installing with NumPy adapter..."
	@uv pip install -e ".[numpy]"

install-pydantic:
	$(ECHO_INFO) "Installing with Pydantic adapter..."
	@uv pip install -e ".[pydantic]"

install-all:
	$(ECHO_INFO) "Installing with all adapters..."
	@uv pip install -e ".[all]"

# =============================================================================
# Build & Distribution
# =============================================================================
build:
	$(ECHO_INFO) "Building distribution packages..."
	@uv build
	$(ECHO_DONE)

# NOTE: publish workflow not finalized. Uncomment when CI/CD pipeline is ready.
# Required: UV_PUBLISH_TOKEN or TWINE_* environment variables in CI secrets.
# publish: build
# 	$(ECHO_INFO) Publishing to PyPI...
# 	@uv publish
# 	$(ECHO_DONE)

# =============================================================================
# CI Pipeline Targets
# =============================================================================
# ci-install: Deterministic install from lockfile (fails if stale)
ci-install:
	$(ECHO_INFO) "Installing from lockfile (frozen)..."
	@uv sync --frozen --all-extras
	$(ECHO_DONE)

# lint-lock: Verify lockfile consistency with pyproject.toml
lint-lock:
	$(ECHO_INFO) "Checking lockfile consistency..."
	@uv lock --check
	$(ECHO_DONE)

# ci: Full CI pipeline (install + lockfile check + verify)
ci: ci-install lint-lock verify
	$(ECHO_INFO) "CI pipeline passed!"

# ci-release: Release pipeline (ci + build artifacts)
ci-release: ci build
	$(ECHO_INFO) "Release pipeline passed!"

# =============================================================================
# Documentation (interactive mode)
# =============================================================================
docs:
	@echo "=== Documentation Generation ==="
	@echo "Output directory: .docs/"
	@echo "This will generate consolidated documentation files:"
	@echo "  - .docs/core.txt (Core modules)"
	@echo "  - .docs/boundary.txt (Boundary contracts)"
	@echo "  - .docs/adapters.txt (Adapter implementations)"
	@echo ""
	@read -p "Continue? (y/N): " confirm && [ "$$confirm" = "y" ] || exit 1
	@echo ""
	@echo "=== Generating documentation in .docs directory ==="
	@mkdir -p .docs
	@uv run python scripts/consolidate.py --root src/crystflux/v1 --format layered --output-dir .docs
	@echo ""
	@echo "Documentation generated in .docs directory"

# =============================================================================
# Cleanup
# =============================================================================
clean:
	$(ECHO_INFO) "Cleaning tool-generated artifacts..."
	
	@# 1. Remove static analysis and test caches (Tier 1 & 2)
	@rm -rf $(CLEAN_CACHES) $(CLEAN_REPORTS)
	@echo "  - [Caches] Removed analysis, test, and coverage artifacts"

	@# 2. Remove build and distribution artifacts (Tier 3)
	@rm -rf $(CLEAN_BUILD)
	@echo "  - [Build]  Removed build and distribution artifacts"

	@# 3. Remove documentation if it exists (Tier 4)
	@if [ -d "$(CLEAN_DOCS)" ]; then rm -rf $(CLEAN_DOCS) && echo "  - [Docs]   Removed generated documentation"; fi

	@# 4. Recursive cleanup for Python runtime artifacts (Tier 1 equivalent)
	@find . -name "__pycache__" -type d -exec rm -rf {} +
	@find . -name "*.py[co]" -type f -delete
	@find . -name "*$$py.class" -type f -delete
	@echo "  - [Python] Removed recursive bytecode and runtime caches"

	$(ECHO_DONE)

# =============================================================================
# Help
# =============================================================================
help:
	@echo "=============================================="
	@echo "CrystFlux - Immutable JSON Crystal Library"
	@echo "=============================================="
	@echo ""
	@echo "Usage: make <target> [CI=1]"
	@echo ""
	@echo "Main targets:"
	@echo "  check-static     Static analysis (lint + typecheck)"
	@echo "  verify           Complete verification (static + test)"
	@echo "  test             Run pytest ($(if $(filter 1,$(CI)),quiet,default))"
	@echo "  coverage         Run tests with coverage report"
	@echo ""
	@echo "Individual checks (main):"
	@echo "  deps-gate        Enforce triadic import rules"
	@echo "  lint, ruff       Run ruff on src, tests"
	@echo "  typecheck        Run basedpyright + mypy"
	@echo "  pyright          Run basedpyright on main (src, tests)"
	@echo "  mypy             Run mypy on main (src, tests)"
	@echo "  mypy-stubs       Check stub consistency"
	@echo ""
	@echo "Static analysis with examples:"
	@echo "  check-static-examples  Full check including examples/"
	@echo "  lint-examples          Run ruff on src, tests, examples"
	@echo "  typecheck-examples     Run basedpyright + mypy on all (including examples)"
	@echo "  pyright-examples       Run basedpyright on all (including examples)"
	@echo "  mypy-examples          Run mypy on all (including examples)"
	@echo ""
	@echo "Installation:"
	@echo "  install          Alias for install-dev (dev dependencies)"
	@echo "  install-numpy    Install with NumPy adapter"
	@echo "  install-pydantic Install with Pydantic adapter"
	@echo "  install-all      Install with all adapters"
	@echo ""
	@echo "Build:"
	@echo "  build            Build distribution packages (uv build)"
	@echo ""
	@echo "CI Pipeline:"
	@echo "  ci               Full CI pipeline (install + lock-check + verify)"
	@echo "  ci-release       Release pipeline (ci + build)"
	@echo "  ci-install       Deterministic install from lockfile"
	@echo "  lint-lock        Verify lockfile matches pyproject.toml"
	@echo ""
	@echo "Utility:"
	@echo "  docs             Generate documentation to .docs/ (interactive)"
	@echo "  clean            Remove generated/cache files"
	@echo "  help             Show this message"
	@echo ""
	@echo "CI mode: CI=1 make check-static  # Quiet output for pipelines"
	@echo ""
	@echo "Environment variables:"
	@echo "  CI=1           Quiet mode for automated pipelines"
	@echo "  MYPY_STRICT=1  Enable mypy strict options (--warn-unused-ignores, etc.)"
	@echo "=============================================="