set shell := ["bash", "-uc"]

# Show the commands intended for day-to-day development.
default:
    @just --list

# Fast feedback for the whole Rust workspace.
check:
    cargo check --workspace --all-targets

# The headless build: a node and a CLI with no overlay, and so no GUI libraries
# (ADR-0016). It is what installs on a server or in a container, and the only thing
# stopping the feature gate rotting is checking that libxkbcommon really is gone.
headless:
    cargo build -p reach --no-default-features
    @! ldd target/debug/reach | grep -q xkbcommon || \
        { echo "reach --no-default-features still links libxkbcommon" >&2; exit 1; }
    @echo "headless build links no GUI libraries"

test:
    @if command -v cargo-nextest >/dev/null 2>&1; then cargo nextest run --workspace; else cargo test --workspace; fi

# Format source files in place.
fmt:
    cargo fmt --all

# Check formatting without changing files.
fmt-check:
    cargo fmt --all -- --check

lint:
    cargo clippy --workspace --all-targets -- -D warnings

# Apply every machine-applicable clippy suggestion, then format. Works on a dirty
# tree on purpose — review the result with `git diff`. What it cannot fix, `just
# lint` still reports.
fix:
    cargo clippy --workspace --all-targets --fix --allow-dirty --allow-staged
    cargo fmt --all

# Backwards-compatible name from the original justfile.
clippy: lint

deny:
    cargo deny check

# The local equivalent of the required CI checks.
ci: fmt-check check lint test headless deny

# Verify the minimum Rust toolchain.
doctor:
    @rustc --version
    @cargo --version
    @just --version
    @if command -v cargo-nextest >/dev/null 2>&1; then cargo nextest --version; else echo "optional: cargo-nextest is not installed (cargo test will be used)"; fi
    @if command -v cargo-deny >/dev/null 2>&1; then cargo deny --version; else echo "optional: cargo-deny is not installed (just deny/ci will be unavailable)"; fi

# Check native dependencies needed by the FUSE mount and the clipboard overlay.
doctor-linux: doctor
    @pkg-config --modversion fuse3
    @pkg-config --modversion xkbcommon
    @command -v fusermount3 >/dev/null

# Check tools needed once the Android Gradle project lands.
doctor-android: doctor
    @java -version
    @command -v sdkmanager >/dev/null
    @command -v cargo-ndk >/dev/null
    @test -n "${ANDROID_HOME:-}" || { echo "ANDROID_HOME is not set" >&2; exit 1; }
    @test -n "${ANDROID_NDK_HOME:-}" || { echo "ANDROID_NDK_HOME is not set" >&2; exit 1; }

# Install this checkout's `reach` into ~/.cargo/bin — one binary: CLI, daemon, overlay.
install:
    cargo install --locked --path crates/reach

# Linked with zig against glibc 2.31 (Debian 11, Ubuntu 20.04) and the standard
# loader, so they run on any distro, not only where they were built. The overlay
# inside it links libxkbcommon from whatever shell builds it; that library may want a newer
# glibc than 2.31, but at run time the system's own copy is loaded, hence
# --allow-shlib-undefined. Needs cargo-zigbuild and zig (both in the CI flake).
# Portable Linux release binaries, packed into dist/ as CI publishes them.
dist target="x86_64-unknown-linux-gnu" glibc="2.31":
    CARGO_TARGET_{{ shoutysnakecase(target) }}_RUSTFLAGS="-C link-arg=-Wl,--allow-shlib-undefined" \
        cargo zigbuild --release --locked --target {{ target }}.{{ glibc }} \
        -p reach
    name="reach-$(git rev-parse --short=12 HEAD)-{{ target }}"; \
    rm -rf "dist/$name" && mkdir -p "dist/$name" && \
    cp target/{{ target }}/release/reach README.md "dist/$name/" && \
    tar -C dist -czf "dist/$name.tar.gz" "$name" && \
    (cd dist && sha256sum "$name.tar.gz" > "$name.tar.gz.sha256") && \
    rm -r "dist/$name" && echo "dist/$name.tar.gz"

# Remove what `just install` put in ~/.cargo/bin.
uninstall:
    cargo uninstall reach

# Run the daemon with one or more shares: `just daemon documents=$HOME/Documents media=$HOME/Videos`
daemon +shares:
    cargo run -p reach -- daemon {{ prepend("--share ", shares) }}

# Cross-build the Android native library (needs cargo-ndk + ANDROID_NDK_HOME).
android-lib:
    cargo ndk -t arm64-v8a -t x86_64 -o android/app/src/main/jniLibs build -p reach-ffi --release

# Generate Kotlin bindings from the built library.
android-bindings: android-lib
    cargo run -p reach-ffi --bin uniffi-bindgen -- generate \
        --library target/aarch64-linux-android/release/libreach_ffi.so \
        --language kotlin --out-dir android/app/src/main/java

# Backwards-compatible alias used by the existing Android notes.
bindgen: android-bindings
