#!/usr/bin/env bash
# Launches Android Studio with environment tuning:
# - Loads secrets from fastlane/.env if present
# - Tunes Gradle/Java memory and parallelism based on machine specs
# - Uses JDK 17 (aligned with INSTALL script)
# - Launches Android Studio binary directly to inherit environment

set -e

# Directory where the script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
ENV_FILE="$PROJECT_ROOT/fastlane/.env"

# ---------- Environment Loading ----------

# Check if fastlane/.env exists and load it
if [[ -f "$ENV_FILE" ]]; then
    if [ -n "${VERBOSE:-}" ]; then
        echo "Loading environment variables from fastlane/.env" >&2
    fi

    # Export all non-comment, non-empty lines from .env file
    set -a  # Automatically export all variables
    while IFS= read -r line || [[ -n "$line" ]]; do
        # Skip empty lines and comments
        if [[ -z "$line" ]] || [[ "$line" =~ ^[[:space:]]*# ]]; then
            continue
        fi

        # Skip lines that don't look like variable assignments
        if [[ ! "$line" =~ ^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*= ]]; then
            continue
        fi

        # Export the variable (eval handles quotes and special chars properly)
        eval "export $line"
    done < "$ENV_FILE"
    set +a

    if [ -n "${VERBOSE:-}" ]; then
        echo "Environment variables loaded successfully" >&2
    fi
else
    if [ -n "${VERBOSE:-}" ]; then
        echo "No fastlane/.env file found. Starting Android Studio without custom environment variables." >&2
    fi
fi

# ---------- Java Environment ----------

# Resolve Java home (prefer JDK 17 per INSTALL script, fallback to 21 or default)
resolve_java_home() {
    local jh=""
    if /usr/libexec/java_home -v 17 >/dev/null 2>&1; then
        jh="$(/usr/libexec/java_home -v 17)"
    elif /usr/libexec/java_home -v 21 >/dev/null 2>&1; then
        jh="$(/usr/libexec/java_home -v 21)"
    else
        jh="$(/usr/libexec/java_home 2>/dev/null || true)"
    fi
    echo "$jh"
}

# ---------- Machine Specs & Tuning ----------

# Compute tuned parameters from machine specs
compute_tuned_params() {
    local cores mem_bytes mem_gb workers xmx xms metas ccsize kxmx kxms

    if [[ "$OSTYPE" == "darwin"* ]]; then
        cores="$(sysctl -n hw.ncpu 2>/dev/null || echo 4)"
        mem_bytes="$(sysctl -n hw.memsize 2>/dev/null || echo 17179869184)"
    elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
        cores="$(nproc 2>/dev/null || echo 4)"
        mem_bytes="$(grep MemTotal /proc/meminfo | awk '{print $2 * 1024}' 2>/dev/null || echo 17179869184)"
    else
        # Fallback defaults
        cores=4
        mem_bytes=17179869184
    fi

    mem_gb=$(( mem_bytes / 1024 / 1024 / 1024 ))

    # Gradle workers: leave one core free; cap to avoid oversubscription
    if (( cores <= 2 )); then
        workers=1
    else
        workers=$(( cores - 1 ))
    fi
    (( workers > 12 )) && workers=12

    # Heap sizing (conservative to leave room for IDE + emulators)
    if   (( mem_gb >= 64 )); then xmx="8g";    xms="2g"
    elif (( mem_gb >= 48 )); then xmx="7g";    xms="2g"
    elif (( mem_gb >= 32 )); then xmx="6g";    xms="1536m"
    elif (( mem_gb >= 24 )); then xmx="5g";    xms="1280m"
    elif (( mem_gb >= 16 )); then xmx="4096m"; xms="1024m"
    elif (( mem_gb >= 12 )); then xmx="3072m"; xms="768m"
    else                        xmx="2048m"; xms="512m"
    fi

    # Kotlin daemon heap
    if   (( mem_gb >= 32 )); then kxmx="3g";    kxms="512m"
    elif (( mem_gb >= 16 )); then kxmx="2048m"; kxms="384m"
    else                        kxmx="1536m"; kxms="256m"
    fi

    metas="512m"     # Metaspace
    ccsize="512m"    # JIT code cache

    echo "$cores;$mem_gb;$workers;$xmx;$xms;$metas;$ccsize;$kxmx;$kxms"
}

# ---------- Studio Discovery ----------

# Find the latest Android Studio version in JetBrains Toolbox
find_toolbox_android_studio() {
    local toolbox_apps_dir="$HOME/Library/Application Support/JetBrains/Toolbox/apps"
    local android_studio_dir="$toolbox_apps_dir/AndroidStudio/ch-0"

    if [[ ! -d "$android_studio_dir" ]]; then
        return 1
    fi

    # Find the latest version directory (sorted by version number)
    local latest_version
    latest_version=$(find "$android_studio_dir" -maxdepth 1 -type d -name "*.*.*.*" 2>/dev/null | LC_ALL=C sort -V | tail -n 1)

    if [[ -z "$latest_version" ]]; then
        return 1
    fi

    local studio_app="$latest_version/Android Studio.app"
    if [[ -d "$studio_app" ]]; then
        echo "$studio_app"
        return 0
    fi

    return 1
}

# ---------- Main Logic ----------

# Compute tuned parameters
read -r CORES MEM_GB WORKERS XMX XMS METAS CACHESIZE KXMX KXMS < <(compute_tuned_params | tr ';' ' ')

# Resolve Java home (macOS only, Linux relies on system default)
if [[ "$OSTYPE" == "darwin"* ]]; then
    JAVA_HOME_RESOLVED="$(resolve_java_home || true)"

    if [[ -z "${JAVA_HOME_RESOLVED:-}" ]]; then
        echo "Error: No system JDK detected. Install JDK 17 (Temurin) via:" >&2
        echo "  brew install --cask temurin@17" >&2
        echo "Or run: ./INSTALL" >&2
        exit 1
    fi

    export JAVA_HOME="$JAVA_HOME_RESOLVED"
    export STUDIO_JDK="$JAVA_HOME"  # Ensures Studio uses the same JDK
fi

# Core JVM/Gradle tuning
COMMON_JVM="-Xms${XMS} -Xmx${XMX} -XX:MaxMetaspaceSize=${METAS} -XX:ReservedCodeCacheSize=${CACHESIZE} \
-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=100 \
-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"

# Gradle environment
export GRADLE_OPTS="${COMMON_JVM} -Dorg.gradle.jvmargs='${COMMON_JVM}' -Dorg.gradle.daemon=true"
export ORG_GRADLE_PROJECT_org_gradle_workers_max="${WORKERS}"
export JAVA_TOOL_OPTIONS="${COMMON_JVM}"

# Kotlin compiler/daemon
export KOTLIN_DAEMON_JVMARGS="-Xms${KXMS} -Xmx${KXMX} -Dfile.encoding=UTF-8 -XX:+UseG1GC -XX:ReservedCodeCacheSize=${CACHESIZE}"

# Gradle build optimizations (can be overridden in gradle.properties)
export ORG_GRADLE_PROJECT_org_gradle_configuration_cache="true"
export ORG_GRADLE_PROJECT_org_gradle_parallel="true"
export ORG_GRADLE_PROJECT_org_gradle_caching="true"

# Detect Android Studio location based on OS
if [[ "$OSTYPE" == "darwin"* ]]; then
    # macOS - Check multiple locations in priority order
    ANDROID_STUDIO_APP=""
    ANDROID_STUDIO_BIN=""

    # 1. Check JetBrains Toolbox installation (preferred)
    if TOOLBOX_STUDIO=$(find_toolbox_android_studio); then
        ANDROID_STUDIO_APP="$TOOLBOX_STUDIO"
        ANDROID_STUDIO_BIN="$ANDROID_STUDIO_APP/Contents/MacOS/studio"
        if [ -n "${VERBOSE:-}" ]; then
            echo "Found Android Studio via JetBrains Toolbox: $ANDROID_STUDIO_APP" >&2
        fi
    # 2. Check standard Applications folder
    elif [[ -d "/Applications/Android Studio.app" ]]; then
        ANDROID_STUDIO_APP="/Applications/Android Studio.app"
        ANDROID_STUDIO_BIN="$ANDROID_STUDIO_APP/Contents/MacOS/studio"
        if [ -n "${VERBOSE:-}" ]; then
            echo "Found Android Studio in Applications folder" >&2
        fi
    # 3. Check user Applications folder
    elif [[ -d "$HOME/Applications/Android Studio.app" ]]; then
        ANDROID_STUDIO_APP="$HOME/Applications/Android Studio.app"
        ANDROID_STUDIO_BIN="$ANDROID_STUDIO_APP/Contents/MacOS/studio"
        if [ -n "${VERBOSE:-}" ]; then
            echo "Found Android Studio in user Applications folder" >&2
        fi
    fi

    if [[ -z "$ANDROID_STUDIO_APP" ]]; then
        echo "Error: Android Studio not found in any of the following locations:" >&2
        echo "  - JetBrains Toolbox: ~/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/" >&2
        echo "  - Standard install: /Applications/Android Studio.app" >&2
        echo "  - User install: ~/Applications/Android Studio.app" >&2
        echo "Please install Android Studio via JetBrains Toolbox or standard installer." >&2
        exit 1
    fi

    if [[ ! -x "$ANDROID_STUDIO_BIN" ]]; then
        echo "Error: Android Studio binary not found or not executable at: $ANDROID_STUDIO_BIN" >&2
        exit 1
    fi

    if [ -n "${VERBOSE:-}" ]; then
        echo "Machine: ${CORES} cores, ${MEM_GB} GB RAM" >&2
        echo "Gradle workers: ${WORKERS}" >&2
        echo "Gradle JVM: Xms=${XMS}, Xmx=${XMX}, Metaspace=${METAS}, CodeCache=${CACHESIZE}" >&2
        echo "Kotlin daemon: Xms=${KXMS}, Xmx=${KXMX}" >&2
        echo "JAVA_HOME: ${JAVA_HOME:-not set}" >&2
        echo "Launching: $ANDROID_STUDIO_BIN \"$PROJECT_ROOT\"" >&2
    fi

    exec "$ANDROID_STUDIO_BIN" "$PROJECT_ROOT"

elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
    # Linux
    ANDROID_STUDIO_BIN="studio.sh"
    STUDIO_PATH=""

    # 1. Check JetBrains Toolbox installation (preferred)
    TOOLBOX_APPS_DIR="$HOME/.local/share/JetBrains/Toolbox/apps"
    ANDROID_STUDIO_DIR="$TOOLBOX_APPS_DIR/android-studio/ch-0"

    if [[ -d "$ANDROID_STUDIO_DIR" ]]; then
        # Find the latest version directory (sorted by version number)
        LATEST_VERSION=$(find "$ANDROID_STUDIO_DIR" -maxdepth 1 -type d -name "*.*.*.*" 2>/dev/null | LC_ALL=C sort -V | tail -n 1)

        if [[ -n "$LATEST_VERSION" ]]; then
            TOOLBOX_STUDIO_BIN="$LATEST_VERSION/bin/$ANDROID_STUDIO_BIN"
            if [[ -f "$TOOLBOX_STUDIO_BIN" ]]; then
                STUDIO_PATH="$TOOLBOX_STUDIO_BIN"
                if [ -n "${VERBOSE:-}" ]; then
                    echo "Found Android Studio via JetBrains Toolbox: $STUDIO_PATH" >&2
                fi
            fi
        fi
    fi

    # 2. Check common Linux installation paths if Toolbox not found
    if [[ -z "$STUDIO_PATH" ]]; then
        STUDIO_PATHS=(
            "$HOME/android-studio/bin/$ANDROID_STUDIO_BIN"
            "/opt/android-studio/bin/$ANDROID_STUDIO_BIN"
            "/usr/local/android-studio/bin/$ANDROID_STUDIO_BIN"
        )

        for studio_path in "${STUDIO_PATHS[@]}"; do
            if [[ -f "$studio_path" ]]; then
                STUDIO_PATH="$studio_path"
                if [ -n "${VERBOSE:-}" ]; then
                    echo "Found Android Studio in standard location: $STUDIO_PATH" >&2
                fi
                break
            fi
        done
    fi

    if [[ -z "$STUDIO_PATH" ]]; then
        echo "Error: Android Studio not found in any of the following locations:" >&2
        echo "  - JetBrains Toolbox: ~/.local/share/JetBrains/Toolbox/apps/android-studio/" >&2
        echo "  - Standard install: ~/android-studio/bin/$ANDROID_STUDIO_BIN" >&2
        echo "  - Standard install: /opt/android-studio/bin/$ANDROID_STUDIO_BIN" >&2
        echo "  - Standard install: /usr/local/android-studio/bin/$ANDROID_STUDIO_BIN" >&2
        echo "Please install Android Studio via JetBrains Toolbox or standard installer." >&2
        exit 1
    fi

    if [ -n "${VERBOSE:-}" ]; then
        echo "Machine: ${CORES} cores, ${MEM_GB} GB RAM" >&2
        echo "Gradle workers: ${WORKERS}" >&2
        echo "Gradle JVM: Xms=${XMS}, Xmx=${XMX}, Metaspace=${METAS}, CodeCache=${CACHESIZE}" >&2
        echo "Kotlin daemon: Xms=${KXMS}, Xmx=${KXMX}" >&2
        echo "Launching: $STUDIO_PATH \"$PROJECT_ROOT\"" >&2
    fi

    exec "$STUDIO_PATH" "$PROJECT_ROOT"

else
    echo "Error: Unsupported operating system: $OSTYPE" >&2
    echo "This script supports macOS and Linux only." >&2
    exit 1
fi
