# ╔══════════════════════════════════════════════════════════════════════════╗
# ║                     🦀 Rust Development Justfile                          ║
# ╚══════════════════════════════════════════════════════════════════════════╝

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

set dotenv-load := true
set windows-shell := ["powershell.exe", "-NoLogo", "-Command"]
set shell := ["bash", "-c"]

# Tool Categories
ESSENTIAL_TOOLS := "cargo-binstall cargo-nextest"
QUALITY_TOOLS   := "cargo-audit cargo-deny cargo-tarpaulin"
UTILITY_TOOLS   := "git-cliff typos-cli jaq cargo-cache cargo-watch cargo-outdated tokei"
ALL_TOOLS       := "{{ESSENTIAL_TOOLS}} {{QUALITY_TOOLS}} {{UTILITY_TOOLS}}"

# Build Flags
ALL_TARGETS_FLAG  := "--all-targets"
ALL_FEATURES_FLAG := "--all-features"

PACKAGES := if os() == "windows" {
    `try { $m = cargo metadata --format-version 1 --no-deps | ConvertFrom-Json; ($m.packages | ForEach-Object { $_.name }) -join ' ' } catch { '' }`
} else {
    `tool=""; if command -v jq >/dev/null 2>&1; then tool=jq; elif command -v jaq >/dev/null 2>&1; then tool=jaq; fi; if [ -n "$tool" ]; then cargo metadata --format-version 1 --no-deps | $tool -r '[.packages[].name] | join(" ")'; fi || echo ''`
}

IS_WORKSPACE := if os() == "windows" {
    `try { $m = cargo metadata --format-version 1 --no-deps | ConvertFrom-Json; if ($m.packages.Count -gt 1) { 'true' } else { 'false' } } catch { 'false' }`
} else {
    `tool=""; if command -v jq >/dev/null 2>&1; then tool=jq; elif command -v jaq >/dev/null 2>&1; then tool=jaq; fi; if [ -n "$tool" ]; then cargo metadata --format-version 1 --no-deps | $tool -r '.packages | length > 1'; else echo false; fi`
}

FEATURES := if os() == "windows" {
    `try { $m = cargo metadata --format-version 1 --no-deps | ConvertFrom-Json; ($m.packages | ForEach-Object { $_.features.PSObject.Properties.Name } | Sort-Object -Unique) -join ' ' } catch { '' }`
} else {
    `tool=""; if command -v jq >/dev/null 2>&1; then tool=jq; elif command -v jaq >/dev/null 2>&1; then tool=jaq; fi; if [ -n "$tool" ]; then cargo metadata --format-version 1 --no-deps | $tool -r '[.packages[].features | keys[]] | unique | sort | join(" ")'; fi || echo ''`
}

BIN := env_var_or_default("BIN", if os() == "windows" {
    `try { $m = cargo metadata --format-version 1 --no-deps | ConvertFrom-Json; ($m.packages | ForEach-Object { $_.targets | Where-Object { $_.kind -contains 'bin' } | ForEach-Object { $_.name } } | Sort-Object -Unique) -join ' ' } catch { '' }`
} else {
    `tool=""; if command -v jq >/dev/null 2>&1; then tool=jq; elif command -v jaq >/dev/null 2>&1; then tool=jaq; fi; if [ -n "$tool" ]; then cargo metadata --format-version 1 --no-deps | $tool -r '[.packages[].targets[] | select(.kind[] == "bin") | .name] | join(" ")'; fi || echo ''`
})

WORKSPACE_FLAG := if os() == "windows" {
    `try { $m = cargo metadata --format-version 1 --no-deps | ConvertFrom-Json; if ($m.packages.Count -gt 1) { '--workspace' } else { '' } } catch { '' }`
} else {
    `tool=""; if command -v jq >/dev/null 2>&1; then tool=jq; elif command -v jaq >/dev/null 2>&1; then tool=jaq; fi; if [ -n "$tool" ]; then cargo metadata --format-version 1 --no-deps | $tool -r 'if (.packages | length) > 1 then "--workspace" else "" end'; fi || echo ''`
}

# ============================================================================
# Default & Help
# ============================================================================

# Default workflow
default: dev

# Show available commands
help:
    @echo "╔══════════════════════════════════════════════════════════════════╗"
    @echo "║                    🦀 Rust Development Commands                   ║"
    @echo "╚══════════════════════════════════════════════════════════════════╝"
    @echo ""
    @just --list --unsorted
    @echo ""
    @echo "📝 Use 'just <command>' to run a command"
    @echo "📋 Use 'just info' to see project information"

# ============================================================================
# 🔄 Workflows
# ============================================================================

# Run complete development workflow
dev: format build
    @echo "╭─────────────────────────────────────╮"
    @echo "│ ✅ Development workflow complete    │"
    @echo "╰─────────────────────────────────────╯"

# Run CI/CD pipeline
ci: format lint check test release
    @echo "╭─────────────────────────────────────╮"
    @echo "│ ✅ CI/CD pipeline complete          │"
    @echo "╰─────────────────────────────────────╯"

# Quick validation
quick: format check test-unit
    @echo "╭─────────────────────────────────────╮"
    @echo "│ ✅ Quick validation complete        │"
    @echo "╰─────────────────────────────────────╯"

# ============================================================================
# 🔨 Build Commands
# ============================================================================

# Check code compilation
check:
    @echo "🔍 Checking code compilation..."
    @cargo check {{WORKSPACE_FLAG}} {{ALL_TARGETS_FLAG}} {{ALL_FEATURES_FLAG}}
    @echo "   └─ ✓ Code compiles successfully"

# Build in debug mode
build:
    @echo "🔨 Building project (debug mode)..."
    @cargo build {{WORKSPACE_FLAG}}
    @echo "   └─ ✓ Debug build complete"

# Build in release mode
release:
    @echo "🚀 Building project (release mode)..."
    @cargo build --release {{WORKSPACE_FLAG}}
    @echo "   └─ ✓ Release build complete"

# Watch for changes and run checks
watch: (_ensure-tool "cargo-watch")
    @echo "👀 Watching for changes..."
    @echo "   └─ Press Ctrl+C to stop"
    @cargo watch -x "check {{WORKSPACE_FLAG}} {{ALL_TARGETS_FLAG}}"

# ============================================================================
# 🧪 Testing
# ============================================================================

# Run all tests
test: test-unit test-doc
    @echo "╭─────────────────────────────────────╮"
    @echo "│ ✅ All tests passed                 │"
    @echo "╰─────────────────────────────────────╯"

# Run unit tests
test-unit: (_ensure-tool "cargo-nextest")
    @echo "🧪 Running unit tests..."
    @cargo nextest run {{WORKSPACE_FLAG}} {{ALL_TARGETS_FLAG}} {{ALL_FEATURES_FLAG}}

# Run documentation tests
test-doc:
    @echo "📚 Running documentation tests..."
    @cargo test --doc {{WORKSPACE_FLAG}}

# Generate coverage report
coverage: (_ensure-tool "cargo-tarpaulin")
    @echo "📊 Generating test coverage report..."
    @cargo tarpaulin {{WORKSPACE_FLAG}} {{ALL_FEATURES_FLAG}} \
        --timeout 120 \
        --out Html --out Lcov --out Xml \
        --output-dir coverage
    @echo "   └─ 📁 Report saved to: coverage/"

# ============================================================================
# 🎨 Code Quality
# ============================================================================

# Format code
format:
    @echo "✨ Formatting code..."
    @cargo fmt --all 
    @echo "   └─ ✓ Code formatted"

# Run linter
lint:
    @echo "🧹 Running Clippy linter..."
    @cargo clippy {{WORKSPACE_FLAG}} {{ALL_TARGETS_FLAG}} {{ALL_FEATURES_FLAG}} -- -D warnings
    @echo "   └─ ✓ No lint issues found"

# Check documentation
lint-docs:
    @echo "📚 Checking documentation..."
    @cargo rustdoc {{WORKSPACE_FLAG}} -- -Zunstable-options --check -Dwarnings
    @echo "   └─ ✓ Documentation is valid"

# Check dependencies
lint-dependencies: (_ensure-tool "cargo-deny")
    @echo "🔍 Checking dependency compliance..."
    @cargo deny check licenses bans sources advisories
    @echo "   └─ ✓ Dependencies compliant"

# Auto-fix issues
fix:
    @echo "🔧 Auto-fixing issues..."
    @cargo clippy {{WORKSPACE_FLAG}} {{ALL_TARGETS_FLAG}} {{ALL_FEATURES_FLAG}} \
        --fix --allow-dirty --allow-staged -- -D warnings
    @just format
    @echo "   └─ ✓ Issues fixed"

# Check spelling
typos: (_ensure-tool "typos-cli")
    @echo "📝 Checking spelling..."
    @typos
    @echo "   └─ ✓ No typos found"

# ============================================================================
# 🔒 Security
# ============================================================================

# Run security audit
security: (_ensure-tool "cargo-audit")
    @echo "🔒 Running security audit..."
    @cargo audit
    @echo "   └─ ✓ No security vulnerabilities found"

# ============================================================================
# 📊 Analysis
# ============================================================================

# Show code statistics
stats: (_ensure-tool "tokei")
    @echo "📊 Code Statistics"
    @echo "════════════════════════════════════"
    @tokei

# Check for outdated dependencies
outdated: (_ensure-tool "cargo-outdated")
    @echo "📦 Checking for dependency updates..."
    @cargo outdated {{WORKSPACE_FLAG}}

# Show dependency tree
deps:
    @echo "🌳 Dependency Tree"
    @echo "════════════════════════════════════"
    @cargo tree {{WORKSPACE_FLAG}}

# ============================================================================
# 📚 Documentation
# ============================================================================

# Generate documentation
docs:
    @echo "📚 Generating documentation..."
    @cargo doc --no-deps {{WORKSPACE_FLAG}}
    @echo "   └─ 📁 Documentation saved to: target/doc/"

# Generate and open documentation
[windows]
docs-open: docs
    @echo "🌐 Opening documentation..."
    @Start-Process "target\doc\index.html" -ErrorAction SilentlyContinue

[unix]
docs-open: docs
    @echo "🌐 Opening documentation..."
    @xdg-open target/doc/index.html 2>/dev/null || \
     open target/doc/index.html 2>/dev/null || \
     echo "   └─ 📁 Documentation at: target/doc/"

# Generate changelog
changelog: (_ensure-tool "git-cliff")
    @echo "📝 Generating changelog..."
    @git cliff -o CHANGELOG.md
    @echo "   └─ 📄 Changelog saved to: CHANGELOG.md"

# ============================================================================
# 🚀 Execution
# ============================================================================

# Run binary
run BIN_NAME=BIN:
    @echo "▶️  Running binary: {{BIN_NAME}}"
    @echo "────────────────────────────────────"
    @cargo run --bin {{BIN_NAME}}

# Run example
run-example EXAMPLE:
    @echo "▶️  Running example: {{EXAMPLE}}"
    @echo "────────────────────────────────────"
    @cargo run --example {{EXAMPLE}}

# ============================================================================
# 🧹 Maintenance
# ============================================================================

# Clean build artifacts
clean:
    @echo "🧹 Cleaning build artifacts..."
    @cargo clean
    @echo "   └─ ✓ Build artifacts cleaned"

# Clean cargo cache
clean-cache: (_ensure-tool "cargo-cache")
    @echo "🧹 Cleaning Cargo cache..."
    @cargo cache --autoclean
    @echo "   └─ ✓ Cache cleaned"

# Deep clean (artifacts + cache)
clean-all: clean clean-cache
    @echo "   └─ ✓ Full cleanup complete"

# ============================================================================
# ℹ️ Information
# ============================================================================

# Display project information
info:
    @echo "╔══════════════════════════════════════════════════════════════════╗"
    @echo "║                      📋 Project Information                       ║"
    @echo "╚══════════════════════════════════════════════════════════════════╝"
    @echo ""
    @echo "  Workspace : {{IS_WORKSPACE}}"
    @echo "  Packages  : {{PACKAGES}}"
    @echo "  Features  : {{FEATURES}}"
    @echo "  Binaries  : {{BIN}}"
    @echo ""

# Display environment variables
env:
    @echo "🌍 Environment Variables"
    @echo "════════════════════════════════════"
    @echo "  IS_WORKSPACE   : {{IS_WORKSPACE}}"
    @echo "  PACKAGES       : {{PACKAGES}}"
    @echo "  FEATURES       : {{FEATURES}}"
    @echo "  BIN            : {{BIN}}"

# ============================================================================
# 🔧 Setup
# ============================================================================

# Setup development environment
[windows]
setup:
    @Write-Host '╔══════════════════════════════════════════════════════════════════╗' -ForegroundColor Cyan
    @Write-Host '║              🔧 Setting up development environment                ║' -ForegroundColor Cyan
    @Write-Host '╚══════════════════════════════════════════════════════════════════╝' -ForegroundColor Cyan
    @foreach ($tool in "{{ESSENTIAL_TOOLS}}".Split()) { just _ensure-tool "$tool" }
    @Write-Host '✅ Development environment ready!' -ForegroundColor Green

[unix]
setup:
    @echo "╔══════════════════════════════════════════════════════════════════╗"
    @echo "║              🔧 Setting up development environment                ║"
    @echo "╚══════════════════════════════════════════════════════════════════╝"
    @for tool in {{ESSENTIAL_TOOLS}}; do just _ensure-tool "$tool"; done
    @echo "✅ Development environment ready!"

# ============================================================================
# 🛠️ Internal Helpers
# ============================================================================

# Ensure tool is installed (Windows)
[windows]
_ensure-tool tool:
    @$exists = Get-Command {{tool}} -ErrorAction SilentlyContinue; \
    if (-not $exists) { \
        just _install-tool {{tool}} \
    }

# Ensure tool is installed (Unix)
[unix]
_ensure-tool tool:
    @bin={{tool}}; \
    if ! command -v "$bin" >/dev/null 2>&1; then \
        just _install-tool {{tool}}; \
    fi

# Install tool (Windows)
[windows]
_install-tool tool:
    @Write-Host "  📦 Installing {{tool}}..." -ForegroundColor Yellow
    @$hasBinstall = Get-Command cargo-binstall -ErrorAction SilentlyContinue; \
    $success = $false; \
    if ($hasBinstall) { \
        $output = cargo binstall {{tool}} --no-confirm --log-level warn 2>&1; \
        if ($LASTEXITCODE -eq 0) { \
            $success = $true \
        } else { \
            Write-Host "     ⚠️  Falling back to cargo install..." -ForegroundColor Yellow; \
            $output = cargo install {{tool}} 2>&1; \
            if ($LASTEXITCODE -eq 0) { $success = $true } \
        } \
    } else { \
        $output = cargo install {{tool}} 2>&1; \
        if ($LASTEXITCODE -eq 0) { $success = $true } \
    }; \
    if ($success) { \
        Write-Host "     └─ ✓ {{tool}} installed" -ForegroundColor Green \
    } else { \
        Write-Host "     ✗ Failed to install {{tool}}" -ForegroundColor Red; \
        $output | Select-Object -Last 5 | ForEach-Object { Write-Host "       $_" -ForegroundColor Red } \
    }

# Install tool (Unix)
[unix]
_install-tool tool:
    @echo "  📦 Installing {{tool}}..."
    @if command -v cargo-binstall >/dev/null 2>&1; then \
        if cargo binstall {{tool}} --no-confirm --log-level warn 2>&1 | grep -q "error\|failed"; then \
            echo "     ⚠️  Falling back to cargo install..."; \
            cargo install {{tool}} 2>&1 | tail -5; \
        fi \
    else \
        cargo install {{tool}} 2>&1 | tail -5; \
    fi && echo "     └─ ✓ {{tool}} installed" || echo "     ✗ Failed to install {{tool}}"

# ============================================================================
# 🚄 Aliases (Shortcuts)
# ============================================================================

# Build
alias b  := build
alias br := release

# Testing
alias t  := test
alias tu := test-unit
alias td := test-doc
alias cov := coverage

# Quality
alias f  := format
alias l  := lint
alias ld := lint-docs
alias lp := lint-dependencies
alias fx := fix
alias ty := typos

# Analysis
alias st := stats
alias od := outdated
alias dp := deps

# Execution
alias r  := run
alias re := run-example

# Documentation
alias d  := docs
alias do := docs-open

# Maintenance
alias c  := check
alias cl := clean
alias clc := clean-cache
alias cla := clean-all

# Security
alias sec := security

# Information
alias i  := info
alias e  := env

# Workflows
alias q  := quick
alias w  := watch

# Setup
alias s  := setup