#!/usr/bin/env bash
# setup_e2e_env.sh — Automated E2E environment setup for ComfyUI + Manager
#
# Creates an isolated ComfyUI installation with ComfyUI-Manager for E2E testing.
# Idempotent: skips setup if marker file and key artifacts already exist.
#
# Input env vars:
#   E2E_ROOT       — target directory (default: auto-generated via mktemp)
#   MANAGER_ROOT   — manager repo root (default: auto-detected from script location)
#   COMFYUI_BRANCH — ComfyUI branch to clone (default: master)
#   PYTHON         — Python executable (default: python3)
#
# Output (last line of stdout):
#   E2E_ROOT=/path/to/environment
#
# Exit: 0=success, 1=failure

set -euo pipefail

# --- Constants ---
COMFYUI_REPO="https://github.com/comfyanonymous/ComfyUI.git"
PYTORCH_CPU_INDEX="https://download.pytorch.org/whl/cpu"
CONFIG_INI_CONTENT="[default]
use_uv = true
use_unified_resolver = true
file_logging = false"

# --- Logging helpers ---
log()  { echo "[setup_e2e] $*"; }
err()  { echo "[setup_e2e] ERROR: $*" >&2; }
die()  { err "$@"; exit 1; }

# --- Detect manager root by walking up from script dir to find pyproject.toml ---
detect_manager_root() {
    local dir
    dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    while [[ "$dir" != "/" ]]; do
        if [[ -f "$dir/pyproject.toml" ]]; then
            echo "$dir"
            return 0
        fi
        dir="$(dirname "$dir")"
    done
    return 1
}

# --- Validate prerequisites ---
validate_prerequisites() {
    local py="${PYTHON:-python3}"
    local missing=()

    command -v git   >/dev/null 2>&1 || missing+=("git")
    command -v uv    >/dev/null 2>&1 || missing+=("uv")
    command -v "$py" >/dev/null 2>&1 || missing+=("$py")

    if [[ ${#missing[@]} -gt 0 ]]; then
        die "Missing prerequisites: ${missing[*]}"
    fi

    # Verify Python version >= 3.9
    local py_version
    py_version=$("$py" -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
    local major minor
    major="${py_version%%.*}"
    minor="${py_version##*.}"
    if [[ "$major" -lt 3 ]] || { [[ "$major" -eq 3 ]] && [[ "$minor" -lt 9 ]]; }; then
        die "Python 3.9+ required, found $py_version"
    fi
    log "Prerequisites OK (python=$py_version, git=$(git --version | awk '{print $3}'), uv=$(uv --version 2>&1 | awk '{print $2}'))"
}

# --- Check idempotency: skip if already set up ---
check_already_setup() {
    local root="$1"
    if [[ -f "$root/.e2e_setup_complete" ]] \
        && [[ -d "$root/comfyui" ]] \
        && [[ -d "$root/venv" ]] \
        && [[ -f "$root/comfyui/user/__manager/config.ini" ]] \
        && [[ -L "$root/comfyui/custom_nodes/ComfyUI-Manager" ]]; then
        log "Environment already set up at $root (marker file exists). Skipping."
        echo "E2E_ROOT=$root"
        exit 0
    fi
}

# --- Verify the setup ---
verify_setup() {
    local root="$1"
    local manager_root="$2"
    local venv_py="$root/venv/bin/python"
    local errors=0

    log "Running verification checks..."

    # Check ComfyUI directory
    if [[ ! -f "$root/comfyui/main.py" ]]; then
        err "Verification FAIL: comfyui/main.py not found"
        ((errors++))
    fi

    # Check venv python
    if [[ ! -x "$venv_py" ]]; then
        err "Verification FAIL: venv python not executable"
        ((errors++))
    fi

    # Check symlink
    local link_target="$root/comfyui/custom_nodes/ComfyUI-Manager"
    if [[ ! -L "$link_target" ]]; then
        err "Verification FAIL: symlink $link_target does not exist"
        ((errors++))
    elif [[ "$(readlink -f "$link_target")" != "$(readlink -f "$manager_root")" ]]; then
        err "Verification FAIL: symlink target mismatch"
        ((errors++))
    fi

    # Check config.ini
    if [[ ! -f "$root/comfyui/user/__manager/config.ini" ]]; then
        err "Verification FAIL: config.ini not found"
        ((errors++))
    fi

    # Check Python imports
    # comfy is a local package inside ComfyUI (not pip-installed), and
    # comfyui_manager.__init__ imports from comfy — both need PYTHONPATH
    if ! PYTHONPATH="$root/comfyui" "$venv_py" -c "import comfy" 2>/dev/null; then
        err "Verification FAIL: 'import comfy' failed"
        ((errors++))
    fi

    if ! PYTHONPATH="$root/comfyui" "$venv_py" -c "import comfyui_manager" 2>/dev/null; then
        err "Verification FAIL: 'import comfyui_manager' failed"
        ((errors++))
    fi

    if [[ "$errors" -gt 0 ]]; then
        die "Verification failed with $errors error(s)"
    fi
    log "Verification OK: all checks passed"
}

# ===== Main =====

# Resolve MANAGER_ROOT
if [[ -z "${MANAGER_ROOT:-}" ]]; then
    MANAGER_ROOT="$(detect_manager_root)" || die "Cannot detect MANAGER_ROOT. Set it explicitly."
fi
MANAGER_ROOT="$(cd "$MANAGER_ROOT" && pwd)"
log "MANAGER_ROOT=$MANAGER_ROOT"

# Validate prerequisites
validate_prerequisites

PYTHON="${PYTHON:-python3}"
COMFYUI_BRANCH="${COMFYUI_BRANCH:-master}"

# Create or use E2E_ROOT
CREATED_BY_US=false
if [[ -z "${E2E_ROOT:-}" ]]; then
    E2E_ROOT="$(mktemp -d -t e2e_comfyui_XXXXXX)"
    CREATED_BY_US=true
    log "Created E2E_ROOT=$E2E_ROOT"
else
    mkdir -p "$E2E_ROOT"
    log "Using E2E_ROOT=$E2E_ROOT"
fi

# Idempotency check
check_already_setup "$E2E_ROOT"

# Cleanup trap: remove E2E_ROOT on failure only if we created it
cleanup_on_failure() {
    local exit_code=$?
    if [[ "$exit_code" -ne 0 ]] && [[ "$CREATED_BY_US" == "true" ]]; then
        err "Setup failed. Cleaning up $E2E_ROOT"
        rm -rf "$E2E_ROOT"
    fi
}
trap cleanup_on_failure EXIT

# Step 1: Clone ComfyUI
log "Step 1/8: Cloning ComfyUI (branch=$COMFYUI_BRANCH)..."
if [[ -d "$E2E_ROOT/comfyui/.git" ]]; then
    log "  ComfyUI already cloned, skipping"
else
    git clone --depth=1 --branch "$COMFYUI_BRANCH" "$COMFYUI_REPO" "$E2E_ROOT/comfyui"
fi

# Step 2: Create virtual environment
log "Step 2/8: Creating virtual environment..."
if [[ -d "$E2E_ROOT/venv" ]]; then
    log "  venv already exists, skipping"
else
    uv venv "$E2E_ROOT/venv"
fi
VENV_PY="$E2E_ROOT/venv/bin/python"

# Step 3: Install ComfyUI dependencies
log "Step 3/8: Installing ComfyUI dependencies (CPU-only)..."
uv pip install \
    --python "$VENV_PY" \
    -r "$E2E_ROOT/comfyui/requirements.txt" \
    --extra-index-url "$PYTORCH_CPU_INDEX"

# Step 4: Install ComfyUI-Manager (editable — venv tracks workspace edits)
# Editable install prevents silent drift between the workspace source and the
# installed package: any change to comfyui_manager/** is visible to E2E
# immediately without re-running this script. The 2026-04-18 junk_value-rejection
# regression (surfaced in WI-E/WI-G, root-caused in WI-I) was masked for weeks by
# a non-editable snapshot — this flag closes that failure mode.
log "Step 4/8: Installing ComfyUI-Manager (editable)..."
uv pip install --python "$VENV_PY" -e "$MANAGER_ROOT"

# Step 5: Create symlink for custom_nodes discovery
log "Step 5/8: Creating custom_nodes symlink..."
mkdir -p "$E2E_ROOT/comfyui/custom_nodes"
local_link="$E2E_ROOT/comfyui/custom_nodes/ComfyUI-Manager"
if [[ -L "$local_link" ]]; then
    log "  Symlink already exists, updating"
    rm -f "$local_link"
fi
ln -s "$MANAGER_ROOT" "$local_link"

# Step 6: Write config.ini to correct path
log "Step 6/8: Writing config.ini..."
mkdir -p "$E2E_ROOT/comfyui/user/__manager"
echo "$CONFIG_INI_CONTENT" > "$E2E_ROOT/comfyui/user/__manager/config.ini"

# Step 7: Create HOME isolation directories
log "Step 7/8: Creating HOME isolation directories..."
mkdir -p "$E2E_ROOT/home/.config"
mkdir -p "$E2E_ROOT/home/.local/share"
mkdir -p "$E2E_ROOT/logs"

# Step 8: Verify setup
log "Step 8/8: Verifying setup..."
verify_setup "$E2E_ROOT" "$MANAGER_ROOT"

# Write marker file
date -Iseconds > "$E2E_ROOT/.e2e_setup_complete"

# Clear the EXIT trap since setup succeeded
trap - EXIT

log "Setup complete."
echo "E2E_ROOT=$E2E_ROOT"
