set shell := ["bash", "-eu", "-o", "pipefail", "-c"]

# List available build and development recipes.
default:
    @just --list

# Build the Rust executables in release mode.
build-rust:
    cargo build --release --locked --bins

# Build the Electron application and its native addon.
build-electron:
    cd electron && bun install --frozen-lockfile --ignore-scripts && bun run build && bun run build-native
    cd electron && if [ ! -x node_modules/electron/dist/electron ] && ! command -v electron >/dev/null 2>&1; then node node_modules/electron/install.js; fi
    cd electron && if [ ! -x node_modules/electron/dist/electron ] && ! command -v electron >/dev/null 2>&1; then echo "Electron runtime download failed; install Electron or retry with network access" >&2; exit 1; fi

# Install the local Wo types package before building comraw.
build-types:
    cd electron/types && bun install --frozen-lockfile

# Build the compositor UI using the types shipped with this checkout.
build-comraw:
    cd comraw && bun install --frozen-lockfile
    mkdir -p comraw/node_modules/@wl-wo
    rm -rf comraw/node_modules/@wl-wo/wo-types
    cp -a electron/types comraw/node_modules/@wl-wo/wo-types
    cd comraw && bun run build

# Build every runtime component in dependency order.
build: build-rust build-electron build-types build-comraw

# Build and install Wo for the current user under ~/.local and XDG directories.
# An existing user config is kept; a first install gets a config.toml derived
# from config.example.toml and serves the packaged comraw build on localhost.
install: build
    #!/usr/bin/env bash
    set -eu
    repo_root="$(pwd)"
    : "${HOME:?HOME must be set for a per-user install}"
    xdg_data_home="${XDG_DATA_HOME:-$HOME/.local/share}"
    data_home="$xdg_data_home/wo"
    config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/wo"
    user_bin="$HOME/.local/bin"
    electron_runtime="$data_home/electron-runtime"
    electron_app="$data_home/electron"
    comraw_dir="$data_home/comraw"
    electron_source="$repo_root/electron/node_modules/electron/dist/electron"
    install_tag="$(date +%Y%m%d%H%M%S).$$"
    electron_runtime_stage="$data_home/.electron-runtime.new.$install_tag"
    electron_app_stage="$data_home/.electron.new.$install_tag"
    comraw_stage="$data_home/.comraw.new.$install_tag"
    trap 'rm -rf "$electron_runtime_stage" "$electron_app_stage" "$comraw_stage"' EXIT

    install -d "$data_home/bin" "$config_dir" "$user_bin"
    install -m755 "$repo_root/target/release/wo" "$data_home/bin/wo"
    install -m755 "$repo_root/target/release/wo-portal" "$data_home/bin/wo-portal"
    install -m755 "$repo_root/target/release/xdg-desktop-portal-wo" "$data_home/bin/xdg-desktop-portal-wo"
    if [ -x "$electron_source" ]; then
      install -d "$electron_runtime_stage"
      cp -a "$repo_root/electron/node_modules/electron/dist/." "$electron_runtime_stage/"
      test -x "$electron_runtime_stage/electron" || { echo "Electron runtime copy is incomplete" >&2; exit 1; }
      electron_bin="$electron_runtime/electron"
    elif command -v electron >/dev/null 2>&1; then
      electron_bin="$(command -v electron)"
    else
      echo "Electron runtime is missing. Install Electron or run: cd electron && node node_modules/electron/install.js" >&2
      exit 1
    fi
    install -d "$electron_app_stage/dist" "$electron_app_stage/native" "$comraw_stage"
    cp -a "$repo_root/electron/dist/." "$electron_app_stage/dist/"
    cp -a "$repo_root/electron/native/." "$electron_app_stage/native/"
    cp -a "$repo_root/comraw/dist/." "$comraw_stage/"

    replace_installed_dir() {
      stage="$1"
      destination="$2"
      if [ -e "$destination" ] || [ -L "$destination" ]; then
        # Keep the prior tree available to processes that were already running.
        mv "$destination" "$destination.previous.$install_tag"
      fi
      mv "$stage" "$destination"
    }
    if [ -d "$electron_runtime_stage" ]; then
      replace_installed_dir "$electron_runtime_stage" "$electron_runtime"
    fi
    replace_installed_dir "$electron_app_stage" "$electron_app"
    replace_installed_dir "$comraw_stage" "$comraw_dir"

    cat > "$user_bin/wo" <<EOF
    #!/bin/sh
    export WO_DATA_DIR="$data_home"
    export WO_ELECTRON_PATH="$electron_bin"
    export WO_ELECTRON_APP_DIR="$electron_app"
    exec "$data_home/bin/wo" "\$@"
    EOF
    chmod 755 "$user_bin/wo"
    install -m755 "$data_home/bin/wo-portal" "$user_bin/wo-portal"
    install -m755 "$data_home/bin/xdg-desktop-portal-wo" "$user_bin/xdg-desktop-portal-wo"

    if [ ! -e "$config_dir/config.toml" ]; then
    cp "$repo_root/config.example.toml" "$config_dir/config.toml"
    fi
    # Existing user configuration is preserved byte-for-byte. Keep any
    # migrations explicit so installation cannot silently change launch
    # commands, display variables, URLs, or user preferences.

    install -D -m644 "$repo_root/packaging/wayland-sessions/wo.desktop" "$xdg_data_home/wayland-sessions/wo.desktop"
    sed -i "s#Exec=wo#Exec=$user_bin/wo#; s#TryExec=wo#TryExec=$user_bin/wo#" "$xdg_data_home/wayland-sessions/wo.desktop"
    install -D -m644 "$repo_root/packaging/portals/wo.portal" "$xdg_data_home/xdg-desktop-portal/portals/wo.portal"
    install -D -m644 "$repo_root/packaging/dbus-services/org.freedesktop.impl.portal.desktop.wo.service" "$xdg_data_home/dbus-1/services/org.freedesktop.impl.portal.desktop.wo.service"
    sed -i "s#Exec=/usr/bin/xdg-desktop-portal-wo#Exec=$user_bin/xdg-desktop-portal-wo#" "$xdg_data_home/dbus-1/services/org.freedesktop.impl.portal.desktop.wo.service"
    echo "Installed Wo for the current user. Ensure $user_bin is on PATH and select Wo from your session manager."

# Run the Rust and Electron test suites.
test:
    cargo test --locked
    cd electron && bun run test

# Build a Debian package for the current Ubuntu/Debian architecture.
ubuntu-deb:
    packaging/ubuntu/build-deb.sh

# Check formatting and compile the Rust binaries without producing a release build.
check:
    cargo fmt --all -- --check
    cargo check --locked --bins

