#!/usr/bin/env bash
# MVGAL Steam Compatibility Tool entry point
# Registered as a Steam compatibility tool so users can select it in
# Steam → Properties → Compatibility → Force the use of a specific
# Steam Play compatibility tool.
#
# SPDX-License-Identifier: MIT

set -euo pipefail

MVGAL_VERSION="0.3.0"
MVGAL_SOCKET="/run/mvgal/mvgal.sock"
MVGAL_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MVGAL_REPO_ROOT="$(cd "$MVGAL_SCRIPT_DIR/.." && pwd)"
MVGAL_PROFILES_DIR="$MVGAL_SCRIPT_DIR/steam_profiles"

# ---------------------------------------------------------------------------
# Logging
# ---------------------------------------------------------------------------

log() {
    echo "[mvgal-steam] $*" >&2
}

# ---------------------------------------------------------------------------
# Detect Steam App ID and apply profile
# ---------------------------------------------------------------------------

detect_app_id() {
    local steam_app_id="${SteamAppId:-${STEAM_APP_ID:-0}}"

    # Try to extract from wine registry if running under Proton
    if [ -n "${WINEPREFIX:-}" ] && command -v wine >/dev/null 2>&1; then
        local reg_value
        reg_value=$(wine reg query "HKEY_LOCAL_MACHINE\\Software\\Wine\\Steam" /v "AppId" 2>/dev/null | awk -F' ' '{print $NF}' || echo "")
        if [ -n "$reg_value" ] && [ "$reg_value" != "" ]; then
            steam_app_id="$reg_value"
        fi
    fi

    echo "$steam_app_id"
}

apply_game_profile() {
    local app_id="$1"

    if [ -f "$MVGAL_PROFILES_DIR/${app_id}.conf" ]; then
        log "Applying profile for App ID $app_id"
        while IFS='=' read -r key value; do
            case "$key" in
                MVGAL_STRATEGY) export MVGAL_STRATEGY="$value" ;;
                MVGAL_FRAME_PACING) export MVGAL_FRAME_PACING="$value" ;;
                MVGAL_POWER_PROFILE) export MVGAL_POWER_PROFILE="$value" ;;
                primary_gpu_mask) export MVGAL_GPU_MASK="$value" ;;
            esac
        done < <(grep -v '^#' "$MVGAL_PROFILES_DIR/${app_id}.conf" 2>/dev/null | \
                sed 's/[[]//g' | sed 's/[]]//g' | \
                awk -F'=' '/=/ {print $1"="$2}')
    fi
}

# ---------------------------------------------------------------------------
# Check MVGAL daemon
# ---------------------------------------------------------------------------

check_daemon() {
    if [ -S "$MVGAL_SOCKET" ]; then
        log "Daemon socket found at $MVGAL_SOCKET"
        return 0
    else
        log "Warning: MVGAL daemon not running (socket $MVGAL_SOCKET absent)"
        log "Start with: pkexec systemctl start mvgald"
        return 1
    fi
}

# ---------------------------------------------------------------------------
# Set up environment for the game
# ---------------------------------------------------------------------------

setup_env() {
    # Detect and apply Steam App ID profile
    local app_id
    app_id=$(detect_app_id)
    if [ "$app_id" != "0" ]; then
        apply_game_profile "$app_id"
    fi

    # Enable MVGAL core + Vulkan ICD (single aggregated device)
    export ENABLE_MVGAL=1
    export MVGAL_USE_ICD="${MVGAL_USE_ICD:-1}"
    export MVGAL_VULKAN_ENABLE=1

    # Default strategy: gaming-optimized AFR
    export MVGAL_STRATEGY="${MVGAL_STRATEGY:-gaming}"

    # Gaming power profile
    export MVGAL_POWER_PROFILE="${MVGAL_POWER_PROFILE:-gaming}"

    # Enable frame pacing by default for gaming
    export MVGAL_FRAME_PACING="${MVGAL_FRAME_PACING:-1}"

    # WoW64 support for 32-bit games
    if ! env | grep -q '^MVGAL_WOW64='; then
        export MVGAL_WOW64="${MVGAL_WOW64:-0}"
    fi

    # Prefer MVGAL Vulkan ICD over per-vendor drivers
    if [ -f "$MVGAL_REPO_ROOT/scripts/mvgal-vulkan-env.sh" ]; then
        # shellcheck source=/dev/null
        source "$MVGAL_REPO_ROOT/scripts/mvgal-vulkan-env.sh"
    else
        local icd_json
        for icd_json in \
            "/usr/share/vulkan/icd.d/mvgal_icd.json" \
            "/usr/local/share/vulkan/icd.d/mvgal_icd.json" \
            "$HOME/.local/share/vulkan/icd.d/mvgal_icd.json"; do
            if [ -f "$icd_json" ]; then
                export VK_ICD_FILENAMES="$icd_json"
                export VK_DRIVER_FILES="$icd_json"
                log "Vulkan ICD: $icd_json"
                break
            fi
        done
    fi

    # Vulkan layer path (scheduling on top of ICD or vendor stack)
    local layer_dir
    for layer_dir in \
        "/usr/share/vulkan/implicit_layer.d" \
        "/usr/local/share/vulkan/implicit_layer.d" \
        "$HOME/.local/share/vulkan/implicit_layer.d"; do
        if [ -f "$layer_dir/VK_LAYER_MVGAL.json" ]; then
            export VK_LAYER_PATH="$layer_dir"
            log "Vulkan layer found at $layer_dir"
            break
        fi
    done

    # Set up LD_PRELOAD for CUDA/OpenCL interception if available
    local preload_lib
    for preload_lib in \
        "/usr/lib/libmvgal_preload.so" \
        "/usr/local/lib/libmvgal_preload.so" \
        "$HOME/.local/lib/libmvgal_preload.so"; do
        if [ -f "$preload_lib" ]; then
            log "MVGAL preload shim found at $preload_lib"
            export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$preload_lib"
            break
        fi
    done

    # Set defaults if not configured
    export MVGAL_GPU_MASK="${MVGAL_GPU_MASK:-0x3}"

    log "MVGAL environment:"
    log "  ENABLE_MVGAL=$ENABLE_MVGAL"
    log "  MVGAL_USE_ICD=${MVGAL_USE_ICD:-0}"
    log "  MVGAL_STRATEGY=$MVGAL_STRATEGY"
    log "  MVGAL_POWER_PROFILE=$MVGAL_POWER_PROFILE"
    log "  MVGAL_FRAME_PACING=$MVGAL_FRAME_PACING"
    log "  MVGAL_GPU_MASK=$MVGAL_GPU_MASK"
    log "  VK_ICD_FILENAMES=${VK_ICD_FILENAMES:-<vendor default>}"
}

# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------

main() {
    log "MVGAL Steam Compatibility Tool v$MVGAL_VERSION"

    if [ $# -eq 0 ]; then
        echo "Usage: $0 <game-executable> [args...]"
        exit 1
    fi

    check_daemon || true   # non-fatal; layer still works without daemon

    setup_env

    log "Launching: $*"
    exec "$@"
}

main "$@"
