# Quadrix Build System
# Desktop application (Tauri) + CLI tools

set windows-shell := ["powershell.exe", "-NoLogo", "-Command"]

# Show available targets
default:
    @just --list

# ─── Prerequisites ────────────────────────────────────────────────────────────

# Check if Rust/Cargo are installed, offer to install if not (Unix)
[private]
[unix]
check-rust:
    #!/usr/bin/env bash
    if ! command -v cargo &> /dev/null || ! command -v rustc &> /dev/null; then
        echo "Rust and Cargo are not installed (required for building)."
        read -p "Would you like to install them automatically via rustup? [y/N] " answer
        if [[ "$answer" =~ ^[Yy]$ ]]; then
            curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
            echo ""
            echo "Rust installed successfully."
            echo "Please restart your shell or run: source \$HOME/.cargo/env"
            echo "Then re-run your build command."
            exit 1
        else
            echo "Please install Rust manually: https://rustup.rs"
            exit 1
        fi
    fi

# Check if Rust/Cargo are installed, offer to install if not (Windows)
[private]
[windows]
check-rust:
    if (-not (Get-Command cargo -ErrorAction SilentlyContinue) -or -not (Get-Command rustc -ErrorAction SilentlyContinue)) { \
        Write-Host "Rust and Cargo are not installed (required for building)."; \
        $answer = Read-Host "Would you like to install them automatically via rustup? [y/N]"; \
        if ($answer -match '^[Yy]$') { \
            Write-Host "Downloading rustup-init.exe..."; \
            Invoke-WebRequest -Uri https://win.rustup.rs/x86_64 -OutFile "$env:TEMP\rustup-init.exe"; \
            & "$env:TEMP\rustup-init.exe" -y; \
            Remove-Item "$env:TEMP\rustup-init.exe"; \
            Write-Host ""; \
            Write-Host "Rust installed successfully."; \
            Write-Host "Please restart your terminal, then re-run your build command."; \
            exit 1 \
        } else { \
            Write-Host "Please install Rust manually: https://rustup.rs"; \
            exit 1 \
        } \
    }

# Check if Node.js/npm are installed (Unix)
[private]
[unix]
check-node:
    #!/usr/bin/env bash
    if ! command -v npm &> /dev/null; then
        echo "Node.js and npm are not installed (required for frontend build)."
        echo "Please install Node.js: https://nodejs.org"
        exit 1
    fi

# Check if Node.js/npm are installed, offer to install if not (Windows)
[private]
[windows]
check-node:
    $env:Path = [Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [Environment]::GetEnvironmentVariable("Path", "User"); \
    if (-not (Get-Command npm.cmd -ErrorAction SilentlyContinue)) { \
        Write-Host "Node.js and npm are not installed (required for frontend build)."; \
        $answer = Read-Host "Would you like to install Node.js automatically via winget? [y/N]"; \
        if ($answer -match '^[Yy]$') { \
            Write-Host "Installing Node.js LTS via winget..."; \
            winget install OpenJS.NodeJS.LTS --accept-source-agreements --accept-package-agreements; \
            Write-Host ""; \
            Write-Host "Node.js installed successfully."; \
            Write-Host "Please restart your terminal, then re-run your build command."; \
            exit 1 \
        } else { \
            Write-Host "Please install Node.js manually: https://nodejs.org"; \
            exit 1 \
        } \
    }

# Install npm dependencies if node_modules is missing (Unix)
[private]
[unix]
_ensure-npm-deps:
    #!/usr/bin/env bash
    if [ ! -d node_modules ]; then
        echo "Installing npm dependencies..."
        npm install
    fi

# Install npm dependencies if node_modules is missing (Windows)
[private]
[windows]
_ensure-npm-deps:
    $env:Path = [Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [Environment]::GetEnvironmentVariable("Path", "User"); \
    if (-not (Test-Path node_modules)) { \
        Write-Host "Installing npm dependencies..."; \
        npm.cmd install \
    }

# Install Tauri CLI (uses cargo-binstall for pre-built binary, falls back to source) (Unix)
[unix]
setup-tauri: check-rust
    command -v cargo-binstall >/dev/null 2>&1 && cargo binstall tauri-cli --no-confirm || cargo install tauri-cli --locked

# Install Tauri CLI (uses cargo-binstall for pre-built binary, falls back to source) (Windows)
[windows]
setup-tauri: check-rust
    try { cargo binstall tauri-cli --no-confirm } catch { cargo install tauri-cli --locked }

# ─── Desktop Application ─────────────────────────────────────────────────────

# Bundle frontend TypeScript into ui/dist/ (Unix)
[private]
[unix]
_build-frontend: check-node _ensure-npm-deps
    npm run build

# Bundle frontend TypeScript into ui/dist/ (Windows)
[private]
[windows]
_build-frontend: check-node _ensure-npm-deps
    $env:Path = [Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [Environment]::GetEnvironmentVariable("Path", "User"); \
    npm.cmd run build

# Build desktop app (dev mode)
build: _build-frontend check-rust
    cargo build --bin quadrix --features desktop

# Run desktop app with hot reload
dev: setup-tauri check-node _ensure-npm-deps
    cargo tauri dev --features desktop

# Build desktop app (release mode)
release: _build-frontend check-rust
    cargo build --release --bin quadrix --features desktop

# Bundle desktop app for distribution (OS-aware)
[macos]
package: package-mac

[windows]
package: package-windows

[linux]
package: package-linux

# Build Linux packages (AppImage, .deb, .rpm) and collect into dist/linux
[linux]
package-linux: setup-tauri check-node _ensure-npm-deps
    #!/usr/bin/env bash
    set -euo pipefail
    echo "Building Linux packages via Tauri..."
    cargo tauri build --features desktop
    mkdir -p dist/linux
    BUNDLE_DIR="target/release/bundle"
    # Collect AppImage
    if ls "$BUNDLE_DIR"/appimage/*.AppImage 1>/dev/null 2>&1; then
        cp "$BUNDLE_DIR"/appimage/*.AppImage dist/linux/
        echo "  Copied AppImage"
    fi
    # Collect .deb
    if ls "$BUNDLE_DIR"/deb/*.deb 1>/dev/null 2>&1; then
        cp "$BUNDLE_DIR"/deb/*.deb dist/linux/
        echo "  Copied .deb"
    fi
    # Collect .rpm
    if ls "$BUNDLE_DIR"/rpm/*.rpm 1>/dev/null 2>&1; then
        cp "$BUNDLE_DIR"/rpm/*.rpm dist/linux/
        echo "  Copied .rpm"
    fi
    # Also copy the plain binary and icon
    if [ -f target/release/quadrix ]; then
        cp target/release/quadrix dist/linux/quadrix
        echo "  Copied binary"
    fi
    cp icons/icon.png dist/linux/quadrix.png
    echo ""
    echo "Built:"
    ls -lh dist/linux/

# Build macOS .app bundle, DMG, and zip
# arch: "universal" (default), "arm", or "intel"
[macos]
package-mac arch="universal": check-rust
    #!/usr/bin/env bash
    set -euo pipefail
    ARCH="{{arch}}"
    echo "Building frontend..."
    npm run build
    APP="dist/macos/Quadrix Desktop.app"
    rm -rf "$APP" dist/macos/*.dmg dist/macos/*.zip
    mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"
    if [ "$ARCH" = "universal" ]; then
        echo "Building release binary (aarch64)..."
        cargo build --release --bin quadrix --features desktop --target aarch64-apple-darwin
        echo "Building release binary (x86_64)..."
        cargo build --release --bin quadrix --features desktop --target x86_64-apple-darwin
        echo "Creating universal binary..."
        lipo -create \
            target/aarch64-apple-darwin/release/quadrix \
            target/x86_64-apple-darwin/release/quadrix \
            -output "$APP/Contents/MacOS/quadrix"
    elif [ "$ARCH" = "arm" ]; then
        echo "Building release binary (aarch64 only)..."
        cargo build --release --bin quadrix --features desktop --target aarch64-apple-darwin
        cp target/aarch64-apple-darwin/release/quadrix "$APP/Contents/MacOS/quadrix"
    elif [ "$ARCH" = "intel" ]; then
        echo "Building release binary (x86_64 only)..."
        cargo build --release --bin quadrix --features desktop --target x86_64-apple-darwin
        cp target/x86_64-apple-darwin/release/quadrix "$APP/Contents/MacOS/quadrix"
    else
        echo "Unknown arch: $ARCH (use universal, arm, or intel)"
        exit 1
    fi
    cp icons/icon.icns "$APP/Contents/Resources/icon.icns"
    cp resources/Info.plist "$APP/Contents/Info.plist"
    echo ""
    echo "Creating zip archive..."
    cd dist/macos && zip -r "Quadrix-Desktop-macos.zip" "Quadrix Desktop.app" && cd ../..
    echo "Creating DMG..."
    DMG_TMP="dist/macos/dmg-staging"
    DMG_RW="dist/macos/Quadrix-Desktop-rw.dmg"
    DMG_FINAL="dist/macos/Quadrix-Desktop-macos.dmg"
    rm -rf "$DMG_TMP" "$DMG_RW"
    mkdir -p "$DMG_TMP"
    cp -R "$APP" "$DMG_TMP/"
    ln -s /Applications "$DMG_TMP/Applications"
    # Create read-write DMG, mount it, set volume icon, then convert to compressed
    hdiutil create -volname "Quadrix Desktop" -srcfolder "$DMG_TMP" \
        -ov -format UDRW "$DMG_RW"
    MOUNT_DIR="/Volumes/Quadrix Desktop"
    # Detach any stale mount from a previous run
    if [ -d "$MOUNT_DIR" ]; then
        echo "Detaching stale DMG mount..."
        hdiutil detach "$MOUNT_DIR" -force 2>/dev/null || true
    fi
    hdiutil attach "$DMG_RW" -readwrite -noverify -mountpoint "$MOUNT_DIR"
    # Wait for mount to settle
    sleep 1
    cp icons/icon.icns "$MOUNT_DIR/.VolumeIcon.icns"
    SetFile -a C "$MOUNT_DIR"
    hdiutil detach "$MOUNT_DIR"
    hdiutil convert "$DMG_RW" -format UDZO -o "$DMG_FINAL" -ov
    rm -f "$DMG_RW"
    rm -rf "$DMG_TMP"
    echo ""
    echo "Built:"
    ls -lh dist/macos/Quadrix-Desktop-macos.zip dist/macos/Quadrix-Desktop-macos.dmg
    ls -lh "$APP/Contents/MacOS/quadrix"

# ─── CLI Tools ────────────────────────────────────────────────────────────────

# Build all CLI tools (dev mode)
build-tools: build-tools-hexplot build-tools-database build-tools-standalone

# Build hexplot tools
build-tools-hexplot:
    cargo build --manifest-path tools/Cargo.toml --bin hexplot --features plotting
    cargo build --manifest-path tools/Cargo.toml --bin hexplot_interactive --features interactive

# Build database CLI tools
build-tools-database:
    cargo build --manifest-path tools/Cargo.toml --bin process_swc_directory --features database

# Build standalone utilities
build-tools-standalone:
    cargo build --manifest-path tools/Cargo.toml --bin swc_info --features cli
    cargo build --manifest-path tools/Cargo.toml --bin test-report --features cli

# Build all CLI tools (release mode)
release-tools: release-tools-hexplot release-tools-database release-tools-standalone

# Build hexplot tools (release)
release-tools-hexplot:
    cargo build --release --manifest-path tools/Cargo.toml --bin hexplot --features plotting
    cargo build --release --manifest-path tools/Cargo.toml --bin hexplot_interactive --features interactive

# Build database CLI tools (release)
release-tools-database:
    cargo build --release --manifest-path tools/Cargo.toml --bin process_swc_directory --features database

# Build standalone utilities (release)
release-tools-standalone:
    cargo build --release --manifest-path tools/Cargo.toml --bin swc_info --features cli
    cargo build --release --manifest-path tools/Cargo.toml --bin test-report --features cli

# ─── Windows Cross-Compilation ────────────────────────────────────────────────

# Setup Windows MSVC cross-compilation toolchains (x64 + ARM64)
setup-windows: check-rust
    rustup target add x86_64-pc-windows-msvc
    rustup target add aarch64-pc-windows-msvc
    cargo install cargo-xwin
    @echo "First build will download Windows SDK (~1GB). This is cached for future builds."

[private]
[windows]
_ensure-windows-toolchain:
    rustup target add x86_64-pc-windows-msvc 2>$null; $null
    rustup target add aarch64-pc-windows-msvc 2>$null; $null

[private]
[unix]
_ensure-windows-toolchain:
    #!/usr/bin/env bash
    set -euo pipefail
    if ! command -v cargo-xwin &> /dev/null; then
        echo "cargo-xwin not found, installing..."
        cargo install cargo-xwin
    fi
    rustup target add x86_64-pc-windows-msvc 2>/dev/null || true
    rustup target add aarch64-pc-windows-msvc 2>/dev/null || true

[private]
[windows]
_cargo-win target *FLAGS:
    cargo build --target {{target}} {{FLAGS}}

[private]
[unix]
_cargo-win target *FLAGS:
    cargo xwin build --target {{target}} {{FLAGS}}

# Cross-compile for Windows ARM64 from Unix using GNU-style clang driver
# (psm crate's aarch64 assembly needs GAS preprocessing that clang-cl skips)
[private]
[unix]
_cargo-win-arm64 *FLAGS:
    cargo xwin build --target aarch64-pc-windows-msvc --cross-compiler clang {{FLAGS}}

# Build desktop app for Windows x64 (dev)
build-windows-x64: _build-frontend _ensure-windows-toolchain
    just _cargo-win x86_64-pc-windows-msvc --bin quadrix --features desktop

# Build desktop app for Windows ARM64 (dev)
build-windows-arm64: _build-frontend _ensure-windows-toolchain
    just _cargo-win-arm64 --bin quadrix --features desktop

# Build desktop app for Windows x64 + ARM64 (dev)
build-windows: build-windows-x64 build-windows-arm64

# Build desktop app for Windows x64 (release)
release-windows-x64: _build-frontend _ensure-windows-toolchain
    just _cargo-win x86_64-pc-windows-msvc --release --bin quadrix --features desktop

# Build desktop app for Windows ARM64 (release)
release-windows-arm64: _build-frontend _ensure-windows-toolchain
    just _cargo-win-arm64 --release --bin quadrix --features desktop

# Build desktop app for Windows x64 + ARM64 (release)
release-windows: release-windows-x64 release-windows-arm64

# Package Windows release binaries
[windows]
package-windows: release-windows
    New-Item -ItemType Directory -Force -Path dist\windows | Out-Null
    Copy-Item target\x86_64-pc-windows-msvc\release\quadrix.exe dist\windows\quadrix-x64.exe
    Copy-Item target\aarch64-pc-windows-msvc\release\quadrix.exe dist\windows\quadrix-arm64.exe
    Write-Host "Packaged: dist\windows\quadrix-x64.exe, dist\windows\quadrix-arm64.exe"

# Package Windows release binaries
[unix]
package-windows: release-windows
    #!/usr/bin/env bash
    set -euo pipefail
    mkdir -p dist/windows
    cp target/x86_64-pc-windows-msvc/release/quadrix.exe dist/windows/quadrix-x64.exe
    cp target/aarch64-pc-windows-msvc/release/quadrix.exe dist/windows/quadrix-arm64.exe
    echo "Packaged: dist/windows/quadrix-x64.exe, dist/windows/quadrix-arm64.exe"

# ─── Linux Cross-Compilation (from macOS) ────────────────────────────────────

# Setup Linux cross-compilation toolchain (requires Docker for cross)
[macos]
setup-linux-cross: check-rust
    #!/usr/bin/env bash
    set -euo pipefail
    if ! command -v cross &> /dev/null; then
        echo "Installing cross..."
        cargo install cross --git https://github.com/cross-rs/cross
    fi
    rustup target add x86_64-unknown-linux-gnu
    rustup target add aarch64-unknown-linux-gnu
    echo ""
    echo "Linux cross-compilation requires a Docker runtime (Docker Desktop or colima)."
    echo "Note: On Apple Silicon, x86_64 builds use QEMU emulation and may be slow (enable Rosetta in your Docker runtime for better performance)."

[private]
[macos]
_ensure-linux-cross:
    #!/usr/bin/env bash
    set -euo pipefail
    if ! command -v cross &> /dev/null; then
        echo "cross not found. Run 'just setup-linux-cross' first."
        exit 1
    fi
    if ! docker info > /dev/null 2>&1; then
        # Try Docker Desktop first, then colima
        if open -a docker 2>/dev/null; then
            echo "Starting Docker Desktop..."
            echo -n "Waiting for Docker"
            for i in $(seq 1 60); do
                if docker info > /dev/null 2>&1; then
                    echo " ready."
                    touch /tmp/.quadrix-docker-method-desktop
                    break
                fi
                echo -n "."
                sleep 2
            done
        elif command -v colima &> /dev/null; then
            echo "Starting colima..."
            colima start
            touch /tmp/.quadrix-docker-method-colima
        else
            echo "No Docker runtime found."
            echo "Install one of:"
            echo "  brew install --cask docker    # Docker Desktop"
            echo "  brew install colima docker    # colima (lightweight)"
            exit 1
        fi
        echo "Starting Colima..."
        colima start
        echo -n "Waiting for Docker"
        for i in $(seq 1 60); do
            if docker info > /dev/null 2>&1; then
                echo " ready."
                touch /tmp/.quadrix-started-docker
                break
            fi
            echo -n "."
            sleep 2
        done
        if ! docker info > /dev/null 2>&1; then
            echo " timed out."
            echo "Docker did not start within 120 seconds."
            exit 1
        fi
    fi
    rustup target add x86_64-unknown-linux-gnu 2>/dev/null || true
    rustup target add aarch64-unknown-linux-gnu 2>/dev/null || true

# Build desktop app for Linux x64 from macOS (dev)
[macos]
build-linux-x64: _build-frontend _ensure-linux-cross
    cross build --target x86_64-unknown-linux-gnu --bin quadrix --features desktop

# Build desktop app for Linux ARM64 from macOS (dev)
[macos]
build-linux-arm64: _build-frontend _ensure-linux-cross
    cross build --target aarch64-unknown-linux-gnu --bin quadrix --features desktop

# Build desktop app for Linux x64 + ARM64 from macOS (dev)
[macos]
build-linux: build-linux-x64 build-linux-arm64

# Build desktop app for Linux x64 from macOS (release)
# Overrides fat LTO to thin LTO because x86_64 cross-compilation runs under
# QEMU on Apple Silicon, and fat LTO crashes the emulated linker.
[macos]
release-linux-x64: _build-frontend _ensure-linux-cross
    CARGO_PROFILE_RELEASE_LTO=thin CARGO_PROFILE_RELEASE_CODEGEN_UNITS=4 CARGO_PROFILE_RELEASE_STRIP=false \
        cross build --release --target x86_64-unknown-linux-gnu --bin quadrix --features desktop

# Build desktop app for Linux ARM64 from macOS (release)
[macos]
release-linux-arm64: _build-frontend _ensure-linux-cross
    cross build --release --target aarch64-unknown-linux-gnu --bin quadrix --features desktop

# Build desktop app for Linux x64 + ARM64 from macOS (release)
[macos]
release-linux: release-linux-x64 release-linux-arm64

# Package Linux release binaries (cross-compiled from macOS)
[macos]
package-linux: release-linux
    #!/usr/bin/env bash
    set -euo pipefail
    mkdir -p dist/linux
    cp target/x86_64-unknown-linux-gnu/release/quadrix dist/linux/quadrix-x64
    cp target/aarch64-unknown-linux-gnu/release/quadrix dist/linux/quadrix-arm64
    cp icons/icon.png dist/linux/quadrix.png
    echo ""
    echo "Packaged:"
    ls -lh dist/linux/
    if [ -f /tmp/.quadrix-docker-method-desktop ]; then
        echo ""
        echo "Stopping Docker Desktop (was started automatically)..."
        osascript -e 'quit app "docker"'
        rm -f /tmp/.quadrix-docker-method-desktop
    elif [ -f /tmp/.quadrix-docker-method-colima ]; then
        echo ""
        echo "Stopping colima (was started automatically)..."
        colima stop
        rm -f /tmp/.quadrix-docker-method-colima
    fi

# ─── macOS Cross-Compilation (from Linux) ────────────────────────────────────

# Setup macOS cross-compilation toolchain (requires Zig)
[linux]
setup-macos-cross: check-rust
    #!/usr/bin/env bash
    set -euo pipefail
    if ! command -v zig &> /dev/null; then
        echo "Zig is required for macOS cross-compilation."
        echo "Install from: https://ziglang.org/download/"
        echo "  or via package manager: apt install zig / snap install zig"
        exit 1
    fi
    if ! command -v cargo-zigbuild &> /dev/null; then
        echo "Installing cargo-zigbuild..."
        cargo install cargo-zigbuild
    fi
    rustup target add x86_64-apple-darwin
    rustup target add aarch64-apple-darwin
    echo "macOS cross-compilation ready."

[private]
[linux]
_ensure-macos-cross:
    #!/usr/bin/env bash
    set -euo pipefail
    if ! command -v cargo-zigbuild &> /dev/null; then
        echo "cargo-zigbuild not found. Run 'just setup-macos-cross' first."
        exit 1
    fi
    if ! command -v zig &> /dev/null; then
        echo "Zig not found. Run 'just setup-macos-cross' for instructions."
        exit 1
    fi
    rustup target add x86_64-apple-darwin 2>/dev/null || true
    rustup target add aarch64-apple-darwin 2>/dev/null || true

# Build desktop app for macOS x64 from Linux (dev)
[linux]
build-mac-x64: _build-frontend _ensure-macos-cross
    cargo zigbuild --target x86_64-apple-darwin --bin quadrix --features desktop

# Build desktop app for macOS ARM64 from Linux (dev)
[linux]
build-mac-arm64: _build-frontend _ensure-macos-cross
    cargo zigbuild --target aarch64-apple-darwin --bin quadrix --features desktop

# Build desktop app for macOS x64 + ARM64 from Linux (dev)
[linux]
build-mac: build-mac-x64 build-mac-arm64

# Build desktop app for macOS x64 from Linux (release)
[linux]
release-mac-x64: _build-frontend _ensure-macos-cross
    cargo zigbuild --release --target x86_64-apple-darwin --bin quadrix --features desktop

# Build desktop app for macOS ARM64 from Linux (release)
[linux]
release-mac-arm64: _build-frontend _ensure-macos-cross
    cargo zigbuild --release --target aarch64-apple-darwin --bin quadrix --features desktop

# Build desktop app for macOS x64 + ARM64 from Linux (release)
[linux]
release-mac: release-mac-x64 release-mac-arm64

# Package macOS release binaries (cross-compiled from Linux, binaries only)
[linux]
package-mac: release-mac
    #!/usr/bin/env bash
    set -euo pipefail
    mkdir -p dist/macos
    cp target/x86_64-apple-darwin/release/quadrix dist/macos/quadrix-x64
    cp target/aarch64-apple-darwin/release/quadrix dist/macos/quadrix-arm64
    echo ""
    echo "Packaged (binaries only — .app bundle and DMG require macOS):"
    ls -lh dist/macos/

# ─── Package All ─────────────────────────────────────────────────────────────

# Package for all platforms reachable from current host
[macos]
package-all: package-mac package-linux package-windows

[linux]
package-all: package-linux package-mac package-windows

[windows]
package-all: package-windows

# ─── Quality Assurance ────────────────────────────────────────────────────────

# Type-check Rust code (no build)
check: check-rust
    cargo check --features desktop

# Type-check TypeScript frontend (no emit) (Unix)
[unix]
check-ts:
    npx tsc --noEmit

# Type-check TypeScript frontend (no emit) (Windows)
[windows]
check-ts:
    npx.cmd tsc --noEmit

# Run all tests (desktop features) and integration test report
test:
    cargo test --features desktop
    cargo run --manifest-path tools/Cargo.toml --bin test-report --features cli

# Run library tests only
test-lib:
    cargo test --lib

# Run tests for a specific module
test-module module:
    cargo test {{module}}

# Run tests for a specific feature (e.g. database, plotting, interactive)
test-feature feature:
    cargo test --features {{feature}}

# Run integration test report
test-report:
    cargo run --manifest-path tools/Cargo.toml --bin test-report --features cli

# Format Rust code
fmt:
    cargo fmt

# Check Rust formatting (CI)
fmt-check:
    cargo fmt -- --check

# Run clippy linter
lint:
    cargo clippy --features desktop -- -D warnings

# Full CI check (format + lint + test)
ci: fmt-check lint test

# ─── Documentation ────────────────────────────────────────────────────────────

# Build and open Rust API docs
docs:
    cargo doc --features desktop --no-deps --open

# Generate Doxygen documentation
doxygen:
    doxygen Doxyfile

# ─── Utilities ────────────────────────────────────────────────────────────────

# Clean all build artifacts
clean:
    cargo clean

# Build everything (desktop + tools, dev mode)
build-all: build build-tools

# Build everything (desktop + tools, release mode)
release-all: release release-tools

# Quick dev cycle (check + library tests)
quick: check test-lib
