#!/bin/bash

# Enable strict mode to exit on errors and unset variables
set -euo pipefail

# Set log file
LOG_FILE="/tmp/mcp.log"

# Clear the log file at the start
> "$LOG_FILE"

# Function for logging
log() {
    local MESSAGE="$1"
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a "$LOG_FILE"
}

# Trap errors and log them before exiting
trap 'log "An error occurred. Exiting with status $?."' ERR

log "Starting jbang setup script."

if [ -n "${VSAIAGENT_PATH_ROOT:-}" ]; then
    RESOLVED_VSAIAGENT_CONFIG_DIR="${VSAIAGENT_PATH_ROOT}/config"
elif [ -n "${VSAIAGENT_CONFIG_DIR:-}" ]; then
    log "VSAIAGENT_CONFIG_DIR is deprecated for desktop shims; prefer VSAIAGENT_PATH_ROOT."
    RESOLVED_VSAIAGENT_CONFIG_DIR="${VSAIAGENT_CONFIG_DIR}"
else
    RESOLVED_VSAIAGENT_CONFIG_DIR="${HOME}/.config/vsaiagent"
fi
MCP_HERMIT_DIR="${RESOLVED_VSAIAGENT_CONFIG_DIR}/mcp-hermit"
mkdir -p "${RESOLVED_VSAIAGENT_CONFIG_DIR}"
HERMIT_SETUP_LOCK_DIR="${RESOLVED_VSAIAGENT_CONFIG_DIR}/.mcp-hermit-setup.lock"
HERMIT_SETUP_LOCK_TIMEOUT=300
HERMIT_SETUP_LOCK_STARTED_AT=$(date +%s)
while ! mkdir "${HERMIT_SETUP_LOCK_DIR}" 2>/dev/null; do
    if [ $(( $(date +%s) - HERMIT_SETUP_LOCK_STARTED_AT )) -ge "${HERMIT_SETUP_LOCK_TIMEOUT}" ]; then
        log "Timed out waiting for ${HERMIT_SETUP_LOCK_DIR}; removing stale lock."
        rm -rf "${HERMIT_SETUP_LOCK_DIR}"
        HERMIT_SETUP_LOCK_STARTED_AT=$(date +%s)
    fi
    sleep 0.1
done
trap 'rm -rf "${HERMIT_SETUP_LOCK_DIR}"; log "An error occurred. Exiting with status $?."' ERR
trap 'rm -rf "${HERMIT_SETUP_LOCK_DIR}"' EXIT

# One-time cleanup for existing Linux users to fix locking issues
CLEANUP_MARKER="${RESOLVED_VSAIAGENT_CONFIG_DIR}/.mcp-hermit-cleanup-v1"
if [[ "$(uname -s)" == "Linux" ]] && [ ! -f "${CLEANUP_MARKER}" ]; then
    log "Performing one-time cleanup of old mcp-hermit directory to fix locking issues."
    if [ -d "${MCP_HERMIT_DIR}" ]; then
        STALE_MCP_HERMIT_DIR="${MCP_HERMIT_DIR}.stale.$$"
        mv "${MCP_HERMIT_DIR}" "${STALE_MCP_HERMIT_DIR}"
        rm -rf "${STALE_MCP_HERMIT_DIR}"
        log "Removed old mcp-hermit directory."
    fi
    touch "${CLEANUP_MARKER}"
    log "Cleanup completed. Marker file created."
fi

# Ensure mcp-hermit/bin exists
log "Creating directory ${MCP_HERMIT_DIR}/bin if it does not exist."
mkdir -p "${MCP_HERMIT_DIR}/bin"

# Change to the mcp-hermit directory
log "Changing to directory ${MCP_HERMIT_DIR}."
cd "${MCP_HERMIT_DIR}"

# Check if hermit binary exists and download if not
if [ ! -f "${MCP_HERMIT_DIR}/bin/hermit" ]; then
    log "Hermit binary not found. Downloading hermit binary."
    curl -fsSL "https://github.com/cashapp/hermit/releases/download/stable/hermit-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/').gz" \
        | gzip -dc > "${MCP_HERMIT_DIR}/bin/hermit" && chmod +x "${MCP_HERMIT_DIR}/bin/hermit"
    log "Hermit binary downloaded and made executable."
else
    log "Hermit binary already exists. Skipping download."
fi

log "setting hermit cache to be local for MCP servers"
mkdir -p "${MCP_HERMIT_DIR}/cache"
export HERMIT_STATE_DIR="${MCP_HERMIT_DIR}/cache"

# Update PATH
export PATH="${MCP_HERMIT_DIR}/bin:${PATH}"
log "Updated PATH to include ${MCP_HERMIT_DIR}/bin."

# Check if hermit environment is already initialized (only run init on first setup)
if [ ! -f "bin/activate-hermit" ]; then
    log "Hermit environment not yet initialized. Setting up hermit."

    # Fix hermit self-update lock issues on Linux by using temp binary for init only
    if [[ "$(uname -s)" == "Linux" ]]; then
        log "Creating temp dir with bin subdirectory for hermit copy to avoid self-update locks."
        HERMIT_TMP_DIR="/tmp/hermit_tmp_$$/bin"
        mkdir -p "${HERMIT_TMP_DIR}"
        cp "${MCP_HERMIT_DIR}/bin/hermit" "${HERMIT_TMP_DIR}/hermit"
        chmod +x "${HERMIT_TMP_DIR}/hermit"
        HERMIT_ORIGINAL_PATH="${PATH}"
        export PATH="${HERMIT_TMP_DIR}:${PATH}"
        HERMIT_CLEANUP_DIR="/tmp/hermit_tmp_$$"
    fi

    # Initialize hermit
    log "Initializing hermit."
    hermit init >> "$LOG_FILE"

    # Clean up temp dir if it was created
    if [[ -n "${HERMIT_CLEANUP_DIR:-}" ]]; then
        log "Cleaning up temporary hermit binary directory."
        export PATH="${HERMIT_ORIGINAL_PATH}"
        rm -rf "${HERMIT_CLEANUP_DIR}"
    fi
else
    log "Hermit environment already initialized. Skipping init."
fi

# Activate the environment with output redirected to log
if [[ "$(uname -s)" == "Linux" ]]; then
    log "Activating hermit environment."
    { . "bin/activate-hermit"; } >> "$LOG_FILE" 2>&1
fi

# Install OpenJDK using hermit
log "Installing OpenJDK with hermit."
hermit install openjdk@17 >> "$LOG_FILE"

# Download and install jbang if not present
if [ ! -f "${MCP_HERMIT_DIR}/bin/jbang" ]; then
    log "Downloading and installing jbang."
    curl -Ls https://sh.jbang.dev | bash -s - app setup
    cp ~/.jbang/bin/jbang "${MCP_HERMIT_DIR}/bin/"
fi

# Verify installations
log "Verifying installation locations:"
log "hermit: $(which hermit)"
log "java: $(which java)"
log "jbang: $(which jbang)"

rm -rf "${HERMIT_SETUP_LOCK_DIR}"
trap 'log "An error occurred. Exiting with status $?."' ERR
trap - EXIT

# Check for custom registry settings
log "Checking for VSAIAGENT_JBANG_REGISTRY environment variable for custom jbang registry setup..."
if [ -n "${VSAIAGENT_JBANG_REGISTRY:-}" ] && curl -s --head --fail "$VSAIAGENT_JBANG_REGISTRY" > /dev/null; then
    log "Checking custom vsaiagent registry availability: $VSAIAGENT_JBANG_REGISTRY"
    log "$VSAIAGENT_JBANG_REGISTRY is accessible. Setting it as JBANG_REPO."
    export JBANG_REPO="$VSAIAGENT_JBANG_REGISTRY"
else
    log "VSAIAGENT_JBANG_REGISTRY is not set or not accessible. Using default jbang repository."
fi

# Trust all jbang scripts that a user might install. Without this, Jbang will attempt to
# prompt the user to trust each script. However, Vsaiagent does not surface this modal and without
# user input, the addExtension method will timeout and fail.
jbang --quiet trust add *

# Final step: Execute jbang with passed arguments, always including --fresh and --quiet
log "Executing 'jbang' command with arguments: $*"
jbang --fresh --quiet "$@" || log "Failed to execute 'jbang' with arguments: $*"

log "jbang setup script completed successfully."
