#!/usr/bin/env bash

# Ensures the required Unity version is installed via Unity Hub.
# Usage: ./ensure_unity_installed.sh [PLATFORM]
#
# PLATFORM can be: mac, windows, ios, or all (default: all)
#
# This script:
# 1. Reads the required version from ProjectSettings/ProjectVersion.txt
# 2. Checks if it's already installed
# 3. If not, attempts to install it via Unity Hub CLI with appropriate modules
#
# Note: Unity Hub CLI installation may require:
# - Unity Hub to be installed
# - User to be logged in to Unity Hub (for some versions)
# - Appropriate licenses

set -euo pipefail

# Read Unity version directly from the project file (maintained by Unity itself)
PROJECT_VERSION_FILE="src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt"
UNITY_VERSION=$(grep "m_EditorVersion:" "$PROJECT_VERSION_FILE" | head -1 | sed 's/m_EditorVersion: //')

UNITY_INSTALL_PATH="/Applications/Unity/Hub/Editor"
UNITY_HUB_CLI="/Applications/Unity Hub.app/Contents/MacOS/Unity Hub"
LOCK_FILE="/tmp/unity_install.lock"
LOCK_TIMEOUT=1800  # 30 minutes max wait for another installation

PLATFORM="${1:-all}"

echo "Required Unity version: ${UNITY_VERSION}"
echo "Platform: ${PLATFORM}"

# Check if Unity is installed and has required modules
check_modules_installed() {
    local unity_path="${UNITY_INSTALL_PATH}/${UNITY_VERSION}"

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

    case "${PLATFORM}" in
        ios)
            # iOS module installs to PlaybackEngines/iOSSupport
            if [ ! -d "${unity_path}/PlaybackEngines/iOSSupport" ]; then
                echo "✗ iOS module not installed for Unity ${UNITY_VERSION}"
                return 1
            fi
            ;;
        mac)
            # Mac IL2CPP module
            if [ ! -d "${unity_path}/PlaybackEngines/MacStandaloneSupport/Variations/macos_development_il2cpp" ] && \
               [ ! -d "${unity_path}/PlaybackEngines/MacStandaloneSupport" ]; then
                echo "✗ Mac IL2CPP module not installed for Unity ${UNITY_VERSION}"
                return 1
            fi
            ;;
        windows)
            # Windows mono module
            if [ ! -d "${unity_path}/PlaybackEngines/WindowsStandaloneSupport" ]; then
                echo "✗ Windows module not installed for Unity ${UNITY_VERSION}"
                return 1
            fi
            ;;
        all)
            # Check all required modules
            local missing=0
            if [ ! -d "${unity_path}/PlaybackEngines/iOSSupport" ]; then
                echo "✗ iOS module missing"
                missing=1
            fi
            if [ ! -d "${unity_path}/PlaybackEngines/MacStandaloneSupport" ]; then
                echo "✗ Mac module missing"
                missing=1
            fi
            if [ ! -d "${unity_path}/PlaybackEngines/WindowsStandaloneSupport" ]; then
                echo "✗ Windows module missing"
                missing=1
            fi
            if [ $missing -eq 1 ]; then
                return 1
            fi
            ;;
    esac

    return 0
}

# Check if already installed with required modules
if check_modules_installed; then
    echo "✓ Unity ${UNITY_VERSION} is already installed with ${PLATFORM} support"
    exit 0
fi

if [ ! -d "${UNITY_INSTALL_PATH}/${UNITY_VERSION}" ]; then
    echo "✗ Unity ${UNITY_VERSION} not found at ${UNITY_INSTALL_PATH}/${UNITY_VERSION}"
fi

# Check if Unity Hub CLI is available
if [ ! -f "${UNITY_HUB_CLI}" ]; then
    echo ""
    echo "Unity Hub CLI not found at ${UNITY_HUB_CLI}"
    echo ""
    echo "To install Unity ${UNITY_VERSION} manually:"
    echo "  1. Open Unity Hub"
    echo "  2. Go to Installs -> Install Editor"
    echo "  3. Select version ${UNITY_VERSION}"
    echo "  4. Add modules based on platform: mac-il2cpp, windows-mono, ios"
    exit 1
fi

# Acquire lock to prevent concurrent installations
acquire_lock() {
    local waited=0
    while ! mkdir "${LOCK_FILE}" 2>/dev/null; do
        if [ $waited -ge $LOCK_TIMEOUT ]; then
            echo "ERROR: Timed out waiting for Unity installation lock after ${LOCK_TIMEOUT}s"
            echo "Another installation may be stuck. Remove ${LOCK_FILE} manually if needed."
            exit 1
        fi
        echo "Another Unity installation is in progress, waiting... (${waited}s)"
        sleep 10
        waited=$((waited + 10))
    done
    # Store PID for debugging
    echo $$ > "${LOCK_FILE}/pid"
    trap release_lock EXIT
}

release_lock() {
    rm -rf "${LOCK_FILE}" 2>/dev/null || true
}

# Re-check after acquiring lock (another process may have installed it)
acquire_lock

if check_modules_installed; then
    echo "✓ Unity ${UNITY_VERSION} with ${PLATFORM} support was installed while waiting for lock"
    exit 0
fi

echo ""

# Determine modules needed for this platform
get_modules_for_platform() {
    case "${PLATFORM}" in
        mac)
            echo "mac-il2cpp"
            ;;
        windows)
            echo "windows-mono"
            ;;
        ios)
            echo "ios"
            ;;
        all)
            echo "mac-il2cpp windows-mono ios"
            ;;
        *)
            echo "Unknown platform: ${PLATFORM}" >&2
            echo "Valid platforms: mac, windows, ios, all" >&2
            exit 1
            ;;
    esac
}

MODULES=$(get_modules_for_platform)

# Check if editor is already installed (just missing modules)
if [ -d "${UNITY_INSTALL_PATH}/${UNITY_VERSION}" ]; then
    echo "Unity ${UNITY_VERSION} is installed but missing modules. Adding modules..."
    echo ""

    # Use install-modules to add modules to existing installation
    INSTALL_CMD=("${UNITY_HUB_CLI}" -- --headless install-modules --version "${UNITY_VERSION}")
    for mod in $MODULES; do
        INSTALL_CMD+=(--module "$mod")
    done
else
    echo "Attempting to install Unity ${UNITY_VERSION} via Unity Hub CLI..."
    echo ""

    # Use install to install editor with modules
    INSTALL_CMD=("${UNITY_HUB_CLI}" -- --headless install --version "${UNITY_VERSION}")
    for mod in $MODULES; do
        INSTALL_CMD+=(--module "$mod")
    done
fi

echo "Running: ${INSTALL_CMD[*]}"
echo ""

# Capture output to check for "already installed" messages
OUTPUT=$("${INSTALL_CMD[@]}" 2>&1) || true
EXIT_CODE=$?
echo "$OUTPUT"

# Check if modules are already installed (Unity Hub returns error but modules are present)
if echo "$OUTPUT" | grep -q "already installed\|No modules found to install"; then
    echo ""
    echo "✓ Modules already installed"
elif [ $EXIT_CODE -eq 0 ]; then
    echo ""
    echo "Unity Hub CLI command completed"
else
    echo ""
    echo "Unity Hub CLI command failed (exit code: ${EXIT_CODE})"
    echo ""
    echo "This may happen if:"
    echo "  - The Unity version is not available for download"
    echo "  - You need to log in to Unity Hub first"
    echo "  - Unity Hub requires a GUI interaction"
    echo ""
    echo "To install manually:"
    echo "  1. Open Unity Hub"
    echo "  2. Go to Installs -> Install Editor"
    echo "  3. Select version ${UNITY_VERSION}"
    echo "  4. Add modules: ${PLATFORM}"
    exit 1
fi

# Verify installation
echo ""
if [ -d "${UNITY_INSTALL_PATH}/${UNITY_VERSION}" ]; then
    echo "✓ Verified: Unity ${UNITY_VERSION} is now installed"
    exit 0
else
    echo "✗ Unity ${UNITY_VERSION} installation could not be verified"
    echo "  Expected path: ${UNITY_INSTALL_PATH}/${UNITY_VERSION}"
    echo ""
    echo "The installation may still be in progress, or may require manual intervention."
    exit 1
fi
