# Provisioning System Build System
# Comprehensive Makefile for building, testing, and distributing the provisioning system

# ============================================================================
# Configuration
# ============================================================================

# Project metadata
PROJECT_NAME := provisioning
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev-$(shell date +%Y%m%d)")
BUILD_TIME := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
GIT_COMMIT := $(shell git rev-parse HEAD 2>/dev/null || echo "unknown")

# Directories
SRC_DIR := $(CURDIR)/..
TOOLS_DIR := $(CURDIR)
BUILD_DIR := $(SRC_DIR)/target
DIST_DIR := $(SRC_DIR)/dist
PACKAGES_DIR := $(SRC_DIR)/packages

# Build configuration
RUST_TARGET := x86_64-unknown-linux-gnu
BUILD_MODE := release
PLATFORMS := linux-amd64,macos-amd64,windows-amd64
VARIANTS := complete,minimal

# Tools
NU := nu
CARGO := cargo
DOCKER := docker
TAR := tar
ZIP := zip

# Flags
VERBOSE := false
DRY_RUN := false
PARALLEL := true

# ============================================================================
# Default target
# ============================================================================

.DEFAULT_GOAL := help

# ============================================================================
# Help system
# ============================================================================

.PHONY: help
help: ## Show this help message
	@echo "Provisioning System Build System"
	@echo "================================="
	@echo ""
	@echo "Usage: make [target] [options]"
	@echo ""
	@echo "Build Targets:"
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "  \033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | grep -E "(build|compile|bundle)"
	@echo ""
	@echo "Package Targets:"
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "  \033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | grep -E "(package|dist|archive)"
	@echo ""
	@echo "Release Targets:"
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "  \033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | grep -E "(release|tag|upload)"
	@echo ""
	@echo "Utility Targets:"
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "  \033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | grep -E "(clean|test|validate|install)"
	@echo ""
	@echo "Variables:"
	@echo "  VERSION=$(VERSION)"
	@echo "  BUILD_MODE=$(BUILD_MODE)"
	@echo "  PLATFORMS=$(PLATFORMS)"
	@echo "  VARIANTS=$(VARIANTS)"
	@echo ""
	@echo "Examples:"
	@echo "  make all                    # Complete build and package"
	@echo "  make build-platform         # Build platform binaries"
	@echo "  make package-all            # Create all distribution packages"
	@echo "  make release VERSION=2.1.0  # Create and upload release"
	@echo "  make clean                  # Clean all build artifacts"

# ============================================================================
# Build targets
# ============================================================================

.PHONY: all
all: clean build-all package-all test-dist ## Complete build, package, and test

.PHONY: build-all
build-all: build-platform build-core validate-kcl ## Build all components

.PHONY: build-platform
build-platform: ## Build platform binaries for all targets
	@echo "Building platform binaries..."
	$(NU) $(TOOLS_DIR)/build/compile-platform.nu \
		--target $(RUST_TARGET) \
		--$(BUILD_MODE) \
		--output-dir $(DIST_DIR)/platform \
		--verbose=$(VERBOSE)

.PHONY: build-core
build-core: ## Bundle core Nushell libraries
	@echo "Building core libraries..."
	$(NU) $(TOOLS_DIR)/build/bundle-core.nu \
		--output-dir $(DIST_DIR)/core \
		--config-dir $(DIST_DIR)/config \
		--validate \
		--exclude-dev \
		--verbose=$(VERBOSE)

.PHONY: validate-kcl
validate-kcl: ## Validate and compile KCL schemas
	@echo "Validating KCL schemas..."
	$(NU) $(TOOLS_DIR)/build/validate-kcl.nu \
		--output-dir $(DIST_DIR)/kcl \
		--format-code \
		--check-dependencies \
		--verbose=$(VERBOSE)

.PHONY: build-cross
build-cross: ## Cross-compile for multiple platforms
	@echo "Cross-compiling for multiple platforms..."
	@for target in $(subst $(comma), ,$(PLATFORMS)); do \
		echo "Building for $$target..."; \
		$(NU) $(TOOLS_DIR)/build/compile-platform.nu \
			--target $$target \
			--$(BUILD_MODE) \
			--output-dir $(DIST_DIR)/platform \
			--verbose=$(VERBOSE) || exit 1; \
	done

# ============================================================================
# Package targets
# ============================================================================

.PHONY: package-all
package-all: dist-generate package-binaries package-containers ## Create all distribution packages

.PHONY: dist-generate
dist-generate: ## Generate complete distributions
	@echo "Generating distributions..."
	$(NU) $(TOOLS_DIR)/distribution/generate-distribution.nu \
		--version $(VERSION) \
		--platforms $(PLATFORMS) \
		--variants $(VARIANTS) \
		--output-dir $(DIST_DIR) \
		--compress \
		--generate-docs \
		--parallel-builds=$(PARALLEL) \
		--validate-output \
		--verbose=$(VERBOSE)

.PHONY: package-binaries
package-binaries: ## Package binaries for distribution
	@echo "Packaging binaries..."
	$(NU) $(TOOLS_DIR)/package/package-binaries.nu \
		--source-dir $(DIST_DIR)/platform \
		--output-dir $(PACKAGES_DIR)/binaries \
		--platforms $(PLATFORMS) \
		--format archive \
		--compress \
		--strip \
		--verbose=$(VERBOSE)

.PHONY: package-containers
package-containers: ## Build container images
	@echo "Building container images..."
	$(NU) $(TOOLS_DIR)/package/build-containers.nu \
		--dist-dir $(DIST_DIR) \
		--tag-prefix $(PROJECT_NAME) \
		--version $(VERSION) \
		--platforms "linux/amd64" \
		--cache \
		--verbose=$(VERBOSE)

.PHONY: create-archives
create-archives: ## Create distribution archives
	@echo "Creating distribution archives..."
	$(NU) $(TOOLS_DIR)/package/create-tarball.nu \
		--dist-dir $(DIST_DIR) \
		--output-dir $(PACKAGES_DIR) \
		--format both \
		--platform all \
		--variant complete \
		--version $(VERSION) \
		--compression-level 6 \
		--checksum \
		--verbose=$(VERBOSE)

.PHONY: create-installers
create-installers: ## Create installation packages
	@echo "Creating installers..."
	@for dist in $(DIST_DIR)/provisioning-$(VERSION)-*-complete; do \
		if [ -d "$$dist" ]; then \
			$(NU) $(TOOLS_DIR)/distribution/create-installer.nu \
				"$$dist" \
				--output-dir $(PACKAGES_DIR)/installers \
				--installer-types shell,package \
				--platforms linux,macos,windows \
				--include-services \
				--create-uninstaller \
				--validate-installer \
				--verbose=$(VERBOSE) || exit 1; \
		fi; \
	done

# ============================================================================
# Release targets
# ============================================================================

.PHONY: release
release: ## Create a complete release (requires VERSION)
	@if [ -z "$(VERSION)" ]; then \
		echo "Error: VERSION must be specified for release"; \
		echo "Usage: make release VERSION=2.1.0"; \
		exit 1; \
	fi
	@echo "Creating release $(VERSION)..."
	$(NU) $(TOOLS_DIR)/release/create-release.nu \
		--version $(VERSION) \
		--asset-dir $(PACKAGES_DIR) \
		--generate-changelog \
		--push-tag \
		--auto-upload \
		--verbose=$(VERBOSE)

.PHONY: release-draft
release-draft: ## Create a draft release
	@echo "Creating draft release..."
	$(NU) $(TOOLS_DIR)/release/create-release.nu \
		--version $(VERSION) \
		--draft \
		--asset-dir $(PACKAGES_DIR) \
		--generate-changelog \
		--push-tag \
		--verbose=$(VERBOSE)

.PHONY: upload-artifacts
upload-artifacts: ## Upload release artifacts
	@echo "Uploading release artifacts..."
	$(NU) $(TOOLS_DIR)/release/upload-artifacts.nu \
		--artifacts-dir $(PACKAGES_DIR) \
		--release-tag v$(VERSION) \
		--targets github,docker \
		--verify-uploads \
		--verbose=$(VERBOSE)

.PHONY: notify-release
notify-release: ## Send release notifications
	@echo "Sending release notifications..."
	$(NU) $(TOOLS_DIR)/release/notify-users.nu \
		--channels slack,discord \
		--release-version $(VERSION) \
		--urgent=false \
		--verbose=$(VERBOSE)

.PHONY: update-registry
update-registry: ## Update package manager registries
	@echo "Updating package registries..."
	$(NU) $(TOOLS_DIR)/release/update-registry.nu \
		--registries homebrew \
		--version $(VERSION) \
		--auto-commit \
		--verbose=$(VERBOSE)

# ============================================================================
# Development and testing targets
# ============================================================================

.PHONY: dev-build
dev-build: ## Quick development build
	@echo "Development build..."
	$(NU) $(TOOLS_DIR)/distribution/generate-distribution.nu quick \
		--platform linux \
		--variant minimal \
		--output-dir $(DIST_DIR)

.PHONY: test-build
test-build: ## Test build system
	@echo "Testing build system..."
	$(NU) $(TOOLS_DIR)/build/compile-platform.nu \
		--target $(RUST_TARGET) \
		--release \
		--output-dir $(DIST_DIR)/test \
		--verbose

.PHONY: test-dist
test-dist: ## Test generated distributions
	@echo "Testing distributions..."
	$(NU) $(TOOLS_DIR)/build/test-distribution.nu \
		--dist-dir $(DIST_DIR) \
		--test-types basic \
		--platform $(shell uname -s | tr '[:upper:]' '[:lower:]') \
		--cleanup \
		--verbose=$(VERBOSE)

.PHONY: validate-all
validate-all: ## Validate all components
	@echo "Validating all components..."
	$(NU) $(TOOLS_DIR)/build/validate-kcl.nu --verbose=$(VERBOSE)
	$(NU) $(TOOLS_DIR)/package/validate-package.nu $(DIST_DIR) --validation-type complete

.PHONY: benchmark
benchmark: ## Run build benchmarks
	@echo "Running build benchmarks..."
	@time make build-platform BUILD_MODE=release
	@echo "Build completed in:"

# ============================================================================
# Documentation targets
# ============================================================================

.PHONY: docs
docs: ## Generate documentation
	@echo "Generating documentation..."
	$(NU) $(TOOLS_DIR)/distribution/generate-docs.nu \
		--output-dir $(DIST_DIR)/docs \
		--doc-types all \
		--format markdown \
		--include-examples \
		--generate-api \
		--create-index \
		--verbose=$(VERBOSE)

.PHONY: docs-serve
docs-serve: docs ## Generate and serve documentation locally
	@echo "Serving documentation on http://localhost:8000"
	@cd $(DIST_DIR)/docs && python3 -m http.server 8000

# ============================================================================
# Utility targets
# ============================================================================

.PHONY: clean
clean: ## Clean all build artifacts
	@echo "Cleaning build artifacts..."
	$(NU) $(TOOLS_DIR)/build/clean-build.nu \
		--scope all \
		--force \
		--verbose=$(VERBOSE)
	rm -rf $(DIST_DIR) $(PACKAGES_DIR) $(BUILD_DIR)

.PHONY: clean-dist
clean-dist: ## Clean only distribution artifacts
	@echo "Cleaning distribution artifacts..."
	$(NU) $(TOOLS_DIR)/build/clean-build.nu \
		--scope dist \
		--force

.PHONY: install
install: ## Install the built system locally
	@echo "Installing system locally..."
	@if [ ! -f $(DIST_DIR)/install.sh ]; then \
		echo "Error: No installer found. Run 'make dist-generate' first."; \
		exit 1; \
	fi
	@cd $(DIST_DIR) && sudo ./install.sh

.PHONY: uninstall
uninstall: ## Uninstall the system
	@echo "Uninstalling system..."
	@if [ -f /usr/local/bin/uninstall-provisioning.sh ]; then \
		sudo /usr/local/bin/uninstall-provisioning.sh; \
	else \
		echo "No uninstaller found. Manual removal required."; \
	fi

.PHONY: status
status: ## Show build system status
	@echo "Build System Status"
	@echo "==================="
	@echo "Project: $(PROJECT_NAME)"
	@echo "Version: $(VERSION)"
	@echo "Git Commit: $(GIT_COMMIT)"
	@echo "Build Time: $(BUILD_TIME)"
	@echo ""
	@echo "Directories:"
	@echo "  Source: $(SRC_DIR)"
	@echo "  Tools: $(TOOLS_DIR)"
	@echo "  Build: $(BUILD_DIR)"
	@echo "  Distribution: $(DIST_DIR)"
	@echo "  Packages: $(PACKAGES_DIR)"
	@echo ""
	@echo "Configuration:"
	@echo "  Rust Target: $(RUST_TARGET)"
	@echo "  Build Mode: $(BUILD_MODE)"
	@echo "  Platforms: $(PLATFORMS)"
	@echo "  Variants: $(VARIANTS)"
	@echo ""
	@$(NU) $(TOOLS_DIR)/distribution/generate-distribution.nu status

.PHONY: info
info: ## Show detailed system information
	@echo "System Information"
	@echo "=================="
	@echo "OS: $(shell uname -s -r)"
	@echo "Architecture: $(shell uname -m)"
	@echo "User: $(shell whoami)"
	@echo "Working Directory: $(CURDIR)"
	@echo ""
	@echo "Tool Versions:"
	@echo "  Nushell: $(shell $(NU) --version 2>/dev/null || echo 'not found')"
	@echo "  Rust: $(shell $(CARGO) --version 2>/dev/null || echo 'not found')"
	@echo "  Docker: $(shell $(DOCKER) --version 2>/dev/null || echo 'not found')"
	@echo "  Git: $(shell git --version 2>/dev/null || echo 'not found')"

# ============================================================================
# CI/CD integration targets
# ============================================================================

.PHONY: ci-build
ci-build: ## CI build pipeline
	@echo "CI Build Pipeline"
	@echo "=================="
	$(MAKE) clean
	$(MAKE) build-all
	$(MAKE) test-dist
	$(MAKE) package-all

.PHONY: ci-test
ci-test: ## CI test pipeline
	@echo "CI Test Pipeline"
	@echo "================"
	$(MAKE) validate-all
	$(MAKE) test-build

.PHONY: ci-release
ci-release: ## CI release pipeline
	@echo "CI Release Pipeline"
	@echo "=================="
	$(MAKE) ci-build
	$(MAKE) create-archives
	$(MAKE) create-installers

.PHONY: cd-deploy
cd-deploy: ## CD deployment pipeline
	@echo "CD Deployment Pipeline"
	@echo "======================"
	$(MAKE) release
	$(MAKE) upload-artifacts
	$(MAKE) update-registry
	$(MAKE) notify-release

# ============================================================================
# Platform-specific targets
# ============================================================================

.PHONY: linux
linux: ## Build for Linux only
	@echo "Building for Linux..."
	$(MAKE) build-platform PLATFORMS=linux-amd64
	$(MAKE) dist-generate PLATFORMS=linux-amd64

.PHONY: macos
macos: ## Build for macOS only
	@echo "Building for macOS..."
	$(MAKE) build-platform PLATFORMS=macos-amd64
	$(MAKE) dist-generate PLATFORMS=macos-amd64

.PHONY: windows
windows: ## Build for Windows only
	@echo "Building for Windows..."
	$(MAKE) build-platform PLATFORMS=windows-amd64
	$(MAKE) dist-generate PLATFORMS=windows-amd64

# ============================================================================
# Debugging targets
# ============================================================================

.PHONY: debug
debug: ## Build with debug information
	@echo "Debug build..."
	$(MAKE) build-all BUILD_MODE=debug VERBOSE=true

.PHONY: debug-info
debug-info: ## Show debug information
	@echo "Debug Information"
	@echo "================="
	@echo "Make Variables:"
	@echo "  MAKEFILE_LIST: $(MAKEFILE_LIST)"
	@echo "  CURDIR: $(CURDIR)"
	@echo "  SHELL: $(SHELL)"
	@echo ""
	@echo "Environment Variables:"
	@env | grep -E "(CARGO|RUST|NU|DOCKER)" | sort

# ============================================================================
# Phony targets declaration
# ============================================================================

.PHONY: help all build-all build-platform build-core validate-kcl build-cross
.PHONY: package-all dist-generate package-binaries package-containers create-archives create-installers
.PHONY: release release-draft upload-artifacts notify-release update-registry
.PHONY: dev-build test-build test-dist validate-all benchmark
.PHONY: docs docs-serve
.PHONY: clean clean-dist install uninstall status info
.PHONY: ci-build ci-test ci-release cd-deploy
.PHONY: linux macos windows debug debug-info

# ============================================================================
# Special targets
# ============================================================================

# Disable built-in rules
.SUFFIXES:

# Keep intermediate files
.SECONDARY:

# Delete targets on error
.DELETE_ON_ERROR:

# Export all variables to sub-make processes
.EXPORT_ALL_VARIABLES:
