#!/usr/bin/env bash
################################################################################
# Cross-Platform Automation Environment Setup Script
# Version: 3.5.0
################################################################################
set -e
IFS=$'\n\t'

################################################################################
# CONFIGURATION
################################################################################
readonly SCRIPT_VERSION="3.5.0"
readonly JAVA_VERSION="${JAVA_VERSION:-17}"
readonly MAVEN_VERSION="${MAVEN_VERSION:-3.9.14}"
readonly REPO_URL=""
readonly TOOLS_HOME="${HOME}/.automation-tools"
readonly LOG_FILE="${LOG_FILE:-${HOME}/automation-setup.log}"

readonly CHROME_WIN_URL="https://dl.google.com/chrome/install/latest/chrome_installer.exe"
readonly FIREFOX_WIN_URL="https://download.mozilla.org/?product=firefox-latest&os=win64&lang=en-US"
readonly CHROME_MAC_URL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
readonly FIREFOX_MAC_URL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"

readonly DOWNLOAD_TIMEOUT=600
readonly CONNECT_TIMEOUT=30
readonly INSTALL_TIMEOUT=180

readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly CYAN='\033[0;36m'
readonly MAGENTA='\033[0;35m'
readonly NC='\033[0m'
readonly BOLD='\033[1m'

declare OS=""
declare ARCH=""
declare ARCHIVE_EXT=""
declare DOWNLOAD_CMD=""
declare SKIP_BROWSERS=false
declare SKIP_GIT_CLONE=false
declare JAVA_HOME_DIR=""
declare MAVEN_HOME_DIR=""
declare FRAMEWORK_DIR=""
declare AUTOMATION_PATH=""

_INSTALL_STATUS_java="pending"
_INSTALL_STATUS_maven="pending"
_INSTALL_STATUS_chrome="pending"
_INSTALL_STATUS_firefox="pending"
_INSTALL_STATUS_repository="pending"

################################################################################
# UTILITY FUNCTIONS
################################################################################
print_message() {
    local level="$1" message="$2" color="$3" timestamp
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo -e "${color}[${timestamp}] [${level}]${NC} ${message}" | tee -a "$LOG_FILE" >&2
}
log_info()    { print_message "INFO   " "$1" "${BLUE}"; }
log_success() { print_message "SUCCESS" "$1" "${GREEN}"; }
log_warning() { print_message "WARNING" "$1" "${YELLOW}"; }
log_error()   { print_message "ERROR  " "$1" "${RED}"; }

log_section() {
    local title="$1"
    { echo ""; echo "================================================================================";
      printf "${BOLD}${CYAN} >> %s${NC}\n" "$title";
      echo "================================================================================"; } | tee -a "$LOG_FILE" >&2
}

command_exists() { command -v "$1" &>/dev/null; }

cleanup() {
    rm -f "$TOOLS_HOME"/*.exe "$TOOLS_HOME"/*.dmg "$TOOLS_HOME"/*.deb 2>/dev/null || true
    exit 0
}
trap cleanup EXIT
trap 'log_warning "Script interrupted - continuing cleanup"; cleanup' INT TERM

################################################################################
# WINDOWS ENVIRONMENT VARIABLE MANAGEMENT
################################################################################
convert_to_windows_path() {
    local bash_path="$1"
    if command_exists cygpath; then
        cygpath -w "$bash_path" 2>/dev/null && return 0
    fi
    if [[ "$bash_path" =~ ^/([a-z])/ ]]; then
        local drive_letter="${BASH_REMATCH[1]}"
        local rest="${bash_path:3}"
        drive_letter=$(echo "$drive_letter" | tr '[:lower:]' '[:upper:]')
        echo "${drive_letter}:\\${rest//\//\\}"
    else
        echo "$bash_path"
    fi
}


################################################################################
# PATH NORMALIZATION (Cross-platform: handles D:\\raj, D:/raj, ~/path, /abs/path)
################################################################################
normalize_input_path() {
    local raw="$1"

    # Replace all backslashes with forward slashes
    local normalized="${raw//\\/\/}"

    # Convert Windows drive letter:
    if [[ "$normalized" =~ ^([A-Za-z]):/(.*)$ ]]; then
        local drive=$(echo "${BASH_REMATCH[1]}" | tr '[:upper:]' '[:lower:]')
        local rest="${BASH_REMATCH[2]}"
        normalized="/${drive}/${rest}"
    fi

    # Expand leading ~ to $HOME
    normalized="${normalized/#\~/$HOME}"

    echo "$normalized"
}
set_windows_env_variable() {
    local var_name="$1"
    local var_value="$2"
    log_info "Setting Windows environment variable: $var_name"
    local windows_value
    windows_value=$(convert_to_windows_path "$var_value")
    local persisted=false

    # Layer 1: PowerShell — writes to HKCU registry (User scope), survives reboots
    if command_exists powershell.exe; then
        local ps_script="[Environment]::SetEnvironmentVariable('$var_name', '$windows_value', 'User')"
        if powershell.exe -NoProfile -NonInteractive -Command "$ps_script" 2>>"$LOG_FILE"; then
            log_success "✓ [$var_name] Persisted via PowerShell → Windows User registry"
            persisted=true
        else
            log_warning "PowerShell registry write failed for $var_name"
        fi
    fi

    # Layer 2: setx — also writes to HKCU registry as fallback / double confirmation
    if command_exists cmd.exe; then
        if command_exists timeout; then
            timeout 5 cmd.exe /c "setx $var_name \"$windows_value\"" >>"$LOG_FILE" 2>&1 && {
                log_success "✓ [$var_name] Confirmed via setx → Windows User registry"
                persisted=true
            } || log_warning "setx failed for $var_name (non-critical if PowerShell succeeded)"
        else
            cmd.exe /c "setx $var_name \"$windows_value\"" >>"$LOG_FILE" 2>&1 || true
            persisted=true
        fi
    fi

    # Layer 3: Always export to current shell session immediately
    export "$var_name"="$var_value"

    if [[ "$persisted" == true ]]; then
        log_success "✓ [$var_name] = $var_value (registry + current session)"
    else
        log_warning "[$var_name] set in current session only — registry write failed"
    fi

    return 0
}

add_to_windows_path() {
    local new_path="$1"
    [[ ! -d "$new_path" ]] && return 0
    log_info "Adding to Windows PATH: $new_path"
    local windows_path
    windows_path=$(convert_to_windows_path "$new_path")
    local persisted=false

    # Layer 1: PowerShell — append to User PATH in registry
    if command_exists powershell.exe; then
        local ps_script="
\$currentPath = [Environment]::GetEnvironmentVariable('Path', 'User');
if (-not \$currentPath) { \$currentPath = '' };
if (\$currentPath -notlike '*$windows_path*') {
    if (\$currentPath -ne '') { \$currentPath += ';' };
    \$currentPath += '$windows_path';
    [Environment]::SetEnvironmentVariable('Path', \$currentPath, 'User');
    Write-Output 'Added to registry PATH';
}
"
        if powershell.exe -NoProfile -NonInteractive -Command "$ps_script" >>"$LOG_FILE" 2>&1; then
            log_success "✓ [PATH] $windows_path → Windows User registry"
            persisted=true
        else
            log_warning "PowerShell PATH update failed for $windows_path"
        fi
    fi

    # Layer 2: setx PATH — fallback if PowerShell failed
    if [[ "$persisted" == false ]] && command_exists cmd.exe; then
        if command_exists timeout; then
            timeout 5 cmd.exe /c "setx PATH \"%PATH%;$windows_path\"" >>"$LOG_FILE" 2>&1 && {
                log_success "✓ [PATH] $windows_path → added via setx"
                persisted=true
            } || log_warning "setx PATH failed for $windows_path"
        fi
    fi

    # Layer 3: Always export to current bash session immediately
    export PATH="$new_path:$PATH"
    log_success "✓ [PATH] $new_path added to current session"
    return 0
}

################################################################################
# SHELL PROFILE MANAGEMENT (FIXED - Persistent on Windows Git Bash)
################################################################################
ensure_bashrc_sourced_from_bash_profile() {
    local bash_profile="$HOME/.bash_profile"
    if [[ ! -f "$bash_profile" ]]; then
        cat > "$bash_profile" << 'PROFILE_EOF'
# Auto-generated by automation-setup script
# Source .bashrc for all Git Bash sessions
if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
fi
PROFILE_EOF
        log_success "✓ Created ~/.bash_profile → sources ~/.bashrc"
    elif ! grep -qF '.bashrc' "$bash_profile" 2>/dev/null; then
        { echo ""; echo "# Added by automation-setup script";
          echo '[ -f "$HOME/.bashrc" ] && . "$HOME/.bashrc"'; } >> "$bash_profile"
        log_info "Linked ~/.bash_profile → ~/.bashrc"
    fi
}

update_profile() {
    local var_name="$1"
    local var_value="$2"

    if [[ "$OS" == "windows" ]]; then
        local bashrc="$HOME/.bashrc"
        touch "$bashrc"
        ensure_bashrc_sourced_from_bash_profile

        local export_line="export ${var_name}=\"${var_value}\""
        if grep -qF "export ${var_name}=" "$bashrc" 2>/dev/null; then
            sed -i "s|^export ${var_name}=.*|${export_line}|" "$bashrc"
            log_info "Updated ${var_name} in ~/.bashrc"
        else
            { echo ""; echo "# Added by automation-setup script"; echo "${export_line}"; } >> "$bashrc"
            log_success "✓ Persisted ${var_name} to ~/.bashrc"
        fi
        export "${var_name}"="${var_value}"
    else
        local profiles=()
        [[ -f "$HOME/.bashrc" ]]       && profiles+=("$HOME/.bashrc")
        [[ -f "$HOME/.zshrc" ]]        && profiles+=("$HOME/.zshrc")
        [[ -f "$HOME/.bash_profile" ]] && profiles+=("$HOME/.bash_profile")
        [[ -f "$HOME/.profile" ]]      && profiles+=("$HOME/.profile")
        # On macOS with zsh, also write to ~/.zprofile so that `zsh -l -c "..."`
        # (login non-interactive shell, used by ProcessBuilder) picks up the env.
        if [[ "$OS" == "mac" ]]; then
            profiles+=("$HOME/.zprofile")
        fi
        [[ ${#profiles[@]} -eq 0 ]]    && profiles+=("$HOME/.bashrc")

        for profile in "${profiles[@]}"; do
            [[ ! -f "$profile" ]] && touch "$profile"
            if ! grep -qF "export ${var_name}=" "$profile" 2>/dev/null; then
                { echo ""; echo "# Added by automation-setup script";
                  echo "export ${var_name}=\"${var_value}\""; } >> "$profile" 2>/dev/null || true
            fi
        done
        export "${var_name}"="${var_value}"
    fi
}

update_path_in_profile() {
    local path_to_add="$1"

    if [[ "$OS" == "windows" ]]; then
        local bashrc="$HOME/.bashrc"
        touch "$bashrc"
        ensure_bashrc_sourced_from_bash_profile
        if ! grep -qF "${path_to_add}" "$bashrc" 2>/dev/null; then
            { echo ""; echo "# Added by automation-setup script";
              echo "export PATH=\"${path_to_add}:\$PATH\""; } >> "$bashrc"
            log_success "✓ Added ${path_to_add} to PATH in ~/.bashrc"
        fi
    else
        local profiles=()
        [[ -f "$HOME/.bashrc" ]] && profiles+=("$HOME/.bashrc")
        [[ -f "$HOME/.zshrc" ]]  && profiles+=("$HOME/.zshrc")
        if [[ "$OS" == "mac" ]]; then
            profiles+=("$HOME/.zprofile")
        fi
        [[ ${#profiles[@]} -eq 0 ]] && profiles+=("$HOME/.bashrc")

        for profile in "${profiles[@]}"; do
            [[ ! -f "$profile" ]] && touch "$profile"
            if ! grep -qF "${path_to_add}" "$profile" 2>/dev/null; then
                { echo ""; echo "# Added by automation-setup script";
                  echo "export PATH=\"${path_to_add}:\$PATH\""; } >> "$profile" 2>/dev/null || true
            fi
        done
    fi
        done
    fi

    # Also export immediately for the current session
    export PATH="${path_to_add}:${PATH}"
    log_success "✓ [PATH] ${path_to_add} added to current session"
}

################################################################################
# PLATFORM DETECTION
################################################################################
detect_platform() {
    log_section "PLATFORM DETECTION"
    case "$(uname -s)" in
        Linux*)           OS="linux"   ;;
        Darwin*)          OS="mac"     ;;
        MINGW*|MSYS*|CYGWIN*) OS="windows" ;;
        *) log_warning "Unknown OS: $(uname -s), assuming Linux-like"; OS="linux" ;;
    esac
    case "$(uname -m)" in
        x86_64|amd64)  ARCH="x64"     ;;
        aarch64|arm64) ARCH="aarch64" ;;
        i386|i686)     ARCH="x86"     ;;
        armv7l)        ARCH="armv7"   ;;
        *) ARCH="x64"; log_warning "Unknown architecture: $(uname -m), assuming x64" ;;
    esac
    [[ "$OS" == "windows" ]] && ARCHIVE_EXT="zip" || ARCHIVE_EXT="tar.gz"
    log_success "Operating System : $OS"
    log_success "Architecture     : $ARCH"
    log_info    "Shell            : $SHELL"
    log_info    "Home             : $HOME"
}

################################################################################
# USER INPUT - INSTALLATION PATH
################################################################################
prompt_installation_path() {
    log_section "AUTOMATION FRAMEWORK INSTALLATION PATH"
    local default_path="${HOME}/automation-framework"
    local user_input=""

    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" >&2
    echo -e "${BOLD} Where do you want to clone the Automation Base Framework?${NC}" >&2
    echo -e "${YELLOW} Default : $default_path${NC}" >&2
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" >&2

    if [[ -t 0 ]] || [[ -e /dev/tty ]]; then
        echo -en "${BOLD}${GREEN} >> Enter Automation path it will take as directory to  generate or execute the testcases (AUTOMATION_PATH) (or press ENTER for default): ${NC}" >&2
        read -r user_input < /dev/tty 2>/dev/null || user_input=""
    else
        log_warning "Non-interactive mode detected — using default path"
        user_input=""
    fi

    if [[ -z "${user_input// }" ]]; then
        AUTOMATION_PATH="$default_path"
        log_info "No input — using default path: $AUTOMATION_PATH"
    else
        AUTOMATION_PATH=$(normalize_input_path "$user_input")
        log_info "User provided path: $AUTOMATION_PATH"
    fi

    FRAMEWORK_DIR="$AUTOMATION_PATH"

    if [[ "$AUTOMATION_PATH" != /* ]]; then
        log_error "Path must be absolute. Got: '$AUTOMATION_PATH'"
        log_warning "Falling back to default: $default_path"
        AUTOMATION_PATH="$default_path"; FRAMEWORK_DIR="$default_path"
    fi

    if mkdir -p "$AUTOMATION_PATH" 2>/dev/null; then
        log_success "✓ Installation directory ready: $AUTOMATION_PATH"
    else
        log_error "Cannot create directory: $AUTOMATION_PATH"
        AUTOMATION_PATH="$default_path"; FRAMEWORK_DIR="$default_path"
        mkdir -p "$AUTOMATION_PATH" 2>/dev/null || true
    fi

    log_info "Persisting AUTOMATION_PATH to shell profiles ..."
    if [[ "$OS" == "windows" ]]; then
        set_windows_env_variable "AUTOMATION_PATH" "$AUTOMATION_PATH"
    fi
    update_profile "AUTOMATION_PATH" "$AUTOMATION_PATH"
    export AUTOMATION_PATH
    log_success "✓ AUTOMATION_PATH = $AUTOMATION_PATH"
}

################################################################################
# DEPENDENCY VERIFICATION
################################################################################
verify_dependencies() {
    log_section "DEPENDENCY VERIFICATION"
    if command_exists curl; then
        DOWNLOAD_CMD="curl"; log_success "✓ curl detected"
    elif command_exists wget; then
        DOWNLOAD_CMD="wget"; log_success "✓ wget detected"
    else
        log_error "Neither curl nor wget found"
        return 1
    fi
    if [[ "$ARCHIVE_EXT" == "zip" ]]; then
        command_exists unzip && log_success "✓ unzip detected" || log_warning "unzip not found"
    else
        command_exists tar && log_success "✓ tar detected" || log_warning "tar not found"
    fi
    return 0
}

################################################################################
# DOWNLOAD FUNCTIONS
################################################################################
download_file() {
    local url="$1" output_path="$2" description="${3:-Downloading file}"
    log_info "$description"
    local max_retries=3 retry=0
    while [[ $retry -lt $max_retries ]]; do
        [[ $retry -gt 0 ]] && log_warning "Retry $retry/$max_retries ..."
        if [[ "$DOWNLOAD_CMD" == "curl" ]]; then
            if curl -L --connect-timeout "$CONNECT_TIMEOUT" --max-time "$DOWNLOAD_TIMEOUT" \
                --fail --progress-bar --output "$output_path" "$url" 2>&1; then
                [[ -f "$output_path" ]] && [[ -s "$output_path" ]] && return 0
            fi
        elif [[ "$DOWNLOAD_CMD" == "wget" ]]; then
            if wget --connect-timeout="$CONNECT_TIMEOUT" --timeout="$DOWNLOAD_TIMEOUT" \
                --tries=1 --show-progress --output-document="$output_path" "$url" 2>&1; then
                [[ -f "$output_path" ]] && [[ -s "$output_path" ]] && return 0
            fi
        fi
        ((retry++)); sleep 2
    done
    log_error "Download failed after $max_retries attempts: $url"
    rm -f "$output_path" 2>/dev/null || true
    return 1
}

################################################################################
# EXTRACTION FUNCTIONS
################################################################################
extract_archive() {
    local archive_path="$1" destination="$2"
    log_info "Extracting: $(basename "$archive_path") ..."
    mkdir -p "$destination" 2>/dev/null || true
    if [[ "$archive_path" =~ \.(tar\.gz|tgz)$ ]]; then
        tar -xzf "$archive_path" -C "$destination" 2>>"$LOG_FILE" && log_success "✓ Extraction completed" && return 0
    elif [[ "$archive_path" =~ \.zip$ ]]; then
        unzip -q -o "$archive_path" -d "$destination" 2>>"$LOG_FILE" && log_success "✓ Extraction completed" && return 0
    fi
    log_error "Extraction failed for: $(basename "$archive_path")"
    return 1
}

################################################################################
# BROWSER DETECTION
################################################################################
is_browser_installed() {
    local browser="$1"
    case "$OS-$browser" in
        windows-chrome)
            [[ -f "/c/Program Files/Google/Chrome/Application/chrome.exe" ]]       && return 0
            [[ -f "/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" ]] && return 0
            [[ -f "$HOME/AppData/Local/Google/Chrome/Application/chrome.exe" ]]    && return 0
            if [[ -n "$LOCALAPPDATA" ]]; then
                local p; p=$(cygpath "$LOCALAPPDATA" 2>/dev/null || echo "$LOCALAPPDATA")
                [[ -f "$p/Google/Chrome/Application/chrome.exe" ]] && return 0
            fi
            return 1 ;;
        windows-firefox)
            [[ -f "/c/Program Files/Mozilla Firefox/firefox.exe" ]]       && return 0
            [[ -f "/c/Program Files (x86)/Mozilla Firefox/firefox.exe" ]] && return 0
            [[ -f "$HOME/AppData/Local/Mozilla Firefox/firefox.exe" ]]    && return 0
            if [[ -n "$LOCALAPPDATA" ]]; then
                local p; p=$(cygpath "$LOCALAPPDATA" 2>/dev/null || echo "$LOCALAPPDATA")
                [[ -f "$p/Mozilla Firefox/firefox.exe" ]] && return 0
            fi
            return 1 ;;
        windows-edge)
            [[ -f "/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe" ]] && return 0
            [[ -f "/c/Program Files/Microsoft/Edge/Application/msedge.exe" ]]        && return 0
            return 1 ;;
        mac-chrome)
            [[ -d "/Applications/Google Chrome.app" ]]      && return 0
            [[ -d "$HOME/Applications/Google Chrome.app" ]] && return 0
            return 1 ;;
        mac-firefox)
            [[ -d "/Applications/Firefox.app" ]]      && return 0
            [[ -d "$HOME/Applications/Firefox.app" ]] && return 0
            return 1 ;;
        mac-safari)  [[ -d "/Applications/Safari.app" ]] ;;
        mac-edge)
            [[ -d "/Applications/Microsoft Edge.app" ]]      && return 0
            [[ -d "$HOME/Applications/Microsoft Edge.app" ]] && return 0
            return 1 ;;
        linux-chrome)   command_exists google-chrome || command_exists google-chrome-stable ;;
        linux-firefox)  command_exists firefox ;;
        linux-chromium) command_exists chromium || command_exists chromium-browser ;;
        *) return 1 ;;
    esac
}

get_browser_location() {
    local browser="$1"
    case "$OS-$browser" in
        windows-chrome)
            [[ -f "/c/Program Files/Google/Chrome/Application/chrome.exe" ]]       && echo "System-wide (Program Files)"    && return
            [[ -f "/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" ]] && echo "System-wide (Program Files x86)" && return
            [[ -f "$HOME/AppData/Local/Google/Chrome/Application/chrome.exe" ]]    && echo "User-level (AppData)"            && return
            echo "Unknown location" ;;
        windows-firefox)
            [[ -f "/c/Program Files/Mozilla Firefox/firefox.exe" ]]       && echo "System-wide (Program Files)"    && return
            [[ -f "/c/Program Files (x86)/Mozilla Firefox/firefox.exe" ]] && echo "System-wide (Program Files x86)" && return
            [[ -f "$HOME/AppData/Local/Mozilla Firefox/firefox.exe" ]]    && echo "User-level (AppData)"            && return
            echo "Unknown location" ;;
        *) echo "Installed" ;;
    esac
}

################################################################################
# JAVA INSTALLATION
################################################################################
install_java() {
    log_section "JAVA DEVELOPMENT KIT (JDK) $JAVA_VERSION SETUP"
    local java_base="$TOOLS_HOME/java"
    JAVA_HOME_DIR="$java_base/jdk-$JAVA_VERSION"
    mkdir -p "$java_base" 2>/dev/null || true

    # Check if a compatible JDK is already on the system PATH
    if command_exists java; then
        local existing_ver
        existing_ver=$(java -version 2>&1 | head -n 1 | grep -oE 'version "([^"]+)"' | grep -oE '[0-9]+' | head -n 1)
        if [[ -n "$existing_ver" ]] && [[ "$existing_ver" -ge "$JAVA_VERSION" ]] 2>/dev/null; then
            log_success "✓ JDK $JAVA_VERSION+ already available on system PATH"
            # Resolve JAVA_HOME from java location
            local java_cmd
            java_cmd=$(command -v java)
            JAVA_HOME_DIR=$(dirname "$(dirname "$java_cmd")")
            # On macOS, /usr/bin/java is a stub — check for real home
            if [[ "$OS" == "mac" ]] && [[ -d "${JAVA_HOME_DIR}/Contents/Home" ]]; then
                JAVA_HOME_DIR="${JAVA_HOME_DIR}/Contents/Home"
            elif [[ "$OS" == "mac" ]] && [[ "$JAVA_HOME_DIR" == "/usr" ]]; then
                JAVA_HOME_DIR=$(/usr/libexec/java_home -v "$JAVA_VERSION" 2>/dev/null || echo "$JAVA_HOME_DIR")
            fi
            _INSTALL_STATUS_java="existing"
            configure_java
            return 0
        fi
    fi

    if [[ -d "$JAVA_HOME_DIR" ]]; then
        log_success "JDK $JAVA_VERSION already installed at $JAVA_HOME_DIR"
        _INSTALL_STATUS_java="existing"
    else
        log_info "Installing JDK $JAVA_VERSION for platform: $OS-$ARCH ..."
        local jdk_url
        case "${OS}-${ARCH}" in
            windows-x64)   jdk_url="https://api.adoptium.net/v3/binary/latest/$JAVA_VERSION/ga/windows/x64/jdk/hotspot/normal/eclipse"   ;;
            windows-x86)   jdk_url="https://api.adoptium.net/v3/binary/latest/$JAVA_VERSION/ga/windows/x86-32/jdk/hotspot/normal/eclipse" ;;
            linux-x64)     jdk_url="https://api.adoptium.net/v3/binary/latest/$JAVA_VERSION/ga/linux/x64/jdk/hotspot/normal/eclipse"      ;;
            linux-aarch64) jdk_url="https://api.adoptium.net/v3/binary/latest/$JAVA_VERSION/ga/linux/aarch64/jdk/hotspot/normal/eclipse"  ;;
            mac-x64)       jdk_url="https://api.adoptium.net/v3/binary/latest/$JAVA_VERSION/ga/mac/x64/jdk/hotspot/normal/eclipse"        ;;
            mac-aarch64)   jdk_url="https://api.adoptium.net/v3/binary/latest/$JAVA_VERSION/ga/mac/aarch64/jdk/hotspot/normal/eclipse"    ;;
            *)
                log_error "Unsupported platform: $OS-$ARCH"
                _INSTALL_STATUS_java="unsupported"
                return 1 ;;
        esac

        local jdk_archive="$java_base/jdk.$ARCHIVE_EXT"
        if download_file "$jdk_url" "$jdk_archive" "Downloading JDK $JAVA_VERSION ..."; then
            if extract_archive "$jdk_archive" "$java_base"; then
                local extracted_dir
                extracted_dir=$(find "$java_base" -maxdepth 1 -type d -name "jdk*" ! -name "jdk-$JAVA_VERSION" 2>/dev/null | head -n 1)
                [[ -n "$extracted_dir" ]] && mv "$extracted_dir" "$JAVA_HOME_DIR" 2>/dev/null || true
                rm -f "$jdk_archive" 2>/dev/null || true
                log_success "✓ JDK $JAVA_VERSION extracted successfully"
                _INSTALL_STATUS_java="success"
            else
                log_error "JDK extraction failed"; _INSTALL_STATUS_java="failed"; return 1
            fi
        else
            log_error "JDK download failed"; _INSTALL_STATUS_java="failed"; return 1
        fi
    fi
    configure_java
}

configure_java() {
    log_section "CONFIGURING JAVA ENVIRONMENT"
    local java_exe
    if [[ "$OS" == "windows" ]]; then
        java_exe=$(find "$JAVA_HOME_DIR" -name "java.exe" -type f 2>/dev/null | grep -E "bin/java\.exe$" | head -n 1)
    elif [[ "$OS" == "mac" ]]; then
        if [[ -d "$JAVA_HOME_DIR/Contents/Home" ]]; then
            java_exe="$JAVA_HOME_DIR/Contents/Home/bin/java"
            JAVA_HOME_DIR="$JAVA_HOME_DIR/Contents/Home"
        else
            java_exe=$(find "$JAVA_HOME_DIR" -name "java" -type f 2>/dev/null | grep -E "bin/java$" | head -n 1)
        fi
    else
        java_exe=$(find "$JAVA_HOME_DIR" -name "java" -type f 2>/dev/null | grep -E "bin/java$" | head -n 1)
    fi

    [[ ! -f "$java_exe" ]] && log_error "Java executable not found in $JAVA_HOME_DIR" && return 1

    local java_bin; java_bin=$(dirname "$java_exe")
    export JAVA_HOME="$JAVA_HOME_DIR"
    log_info "JAVA_HOME set to: $JAVA_HOME"

    if [[ "$OS" == "windows" ]]; then
        set_windows_env_variable "JAVA_HOME" "$JAVA_HOME"
        add_to_windows_path "$java_bin"
    fi
    update_profile "JAVA_HOME" "$JAVA_HOME"
    update_path_in_profile "$java_bin"
    export PATH="$java_bin:$PATH"

    local java_ver_out; java_ver_out=$("$java_exe" -version 2>&1 | head -n 1)
    log_success "✓ Java configured — $java_ver_out"
}

################################################################################
# MAVEN INSTALLATION
################################################################################
install_maven() {
    log_section "APACHE MAVEN SETUP"

    # ── 1. Check if mvn is already available system-wide (any version) ──
    if command_exists mvn; then
        local system_mvn_ver
        system_mvn_ver=$(mvn -version 2>&1 | head -n 1)
        log_success "✓ Maven already available in system PATH — skipping download"
        log_success "  Detected: $system_mvn_ver"
        _INSTALL_STATUS_maven="existing"

        # Extract and export MAVEN_HOME from mvn output if not already set
        if [[ -z "$MAVEN_HOME" ]]; then
            local detected_home
            detected_home=$(mvn -version 2>&1 | grep -i "Maven home:" | sed 's/Maven home: //' | xargs)
            if [[ -n "$detected_home" ]]; then
                MAVEN_HOME_DIR="$detected_home"
                export MAVEN_HOME="$MAVEN_HOME_DIR"
                log_info "  MAVEN_HOME detected: $MAVEN_HOME"
            fi
        fi
        # Persist MAVEN_HOME to profiles so it's available in new shells
        if [[ -n "$MAVEN_HOME" ]]; then
            update_profile "MAVEN_HOME" "$MAVEN_HOME"
        fi
        return 0
    fi

    # ── 2. Check if already downloaded by this script into TOOLS_HOME ──
    log_section "APACHE MAVEN $MAVEN_VERSION SETUP"
    local maven_base="$TOOLS_HOME/maven"
    MAVEN_HOME_DIR="$maven_base/apache-maven-$MAVEN_VERSION"
    mkdir -p "$maven_base" 2>/dev/null || true

    if [[ -f "$MAVEN_HOME_DIR/bin/mvn" ]] || [[ -f "$MAVEN_HOME_DIR/bin/mvn.cmd" ]]; then
        log_success "Maven $MAVEN_VERSION already installed at $MAVEN_HOME_DIR"
        _INSTALL_STATUS_maven="existing"
    else
        # ── 3. Download Maven ──
        log_info "Installing Maven $MAVEN_VERSION ..."
        local maven_url
        if [[ "$OS" == "windows" ]]; then
            maven_url="https://archive.apache.org/dist/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.zip"
        else
            maven_url="https://archive.apache.org/dist/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz"
        fi
        local maven_archive="$maven_base/maven.$ARCHIVE_EXT"
        if download_file "$maven_url" "$maven_archive" "Downloading Maven $MAVEN_VERSION ..."; then
            if extract_archive "$maven_archive" "$maven_base"; then
                rm -f "$maven_archive" 2>/dev/null || true
                log_success "✓ Maven $MAVEN_VERSION extracted successfully"
                _INSTALL_STATUS_maven="success"
            else
                log_error "Maven extraction failed"; _INSTALL_STATUS_maven="failed"; return 1
            fi
        else
            log_error "Maven download failed"; _INSTALL_STATUS_maven="failed"; return 1
        fi
    fi
    configure_maven
}

configure_maven() {
    log_section "CONFIGURING MAVEN ENVIRONMENT"
    export MAVEN_HOME="$MAVEN_HOME_DIR"
    local maven_bin="$MAVEN_HOME_DIR/bin"
    log_info "MAVEN_HOME set to: $MAVEN_HOME"

    if [[ "$OS" == "windows" ]]; then
        set_windows_env_variable "MAVEN_HOME" "$MAVEN_HOME"
        add_to_windows_path "$maven_bin"
    fi
    update_profile "MAVEN_HOME" "$MAVEN_HOME"
    update_path_in_profile "$maven_bin"
    export PATH="$maven_bin:$PATH"

    local mvn_cmd="$maven_bin/mvn"
    [[ "$OS" == "windows" ]] && mvn_cmd="$maven_bin/mvn.cmd"
    if [[ -f "$mvn_cmd" ]]; then
        local mvn_ver_out; mvn_ver_out=$("$mvn_cmd" -version 2>&1 | head -n 1)
        log_success "✓ Maven configured — $mvn_ver_out"
    else
        log_warning "Maven command not found at $mvn_cmd"
    fi
}

################################################################################
# GIT VALIDATION
################################################################################
validate_git() {
    log_section "GIT VERSION CONTROL VALIDATION"
    if command_exists git; then
        log_success "✓ Git detected: $(git --version 2>&1 | head -n 1)"; return 0
    else
        log_warning "Git not found"
        log_info "Install: sudo apt install git (Linux) or brew install git (macOS)"
        return 1
    fi
}

################################################################################
# BROWSER INSTALLATION - WINDOWS
################################################################################
install_chrome_windows() {
    if is_browser_installed "chrome"; then
        log_success "✓ Chrome already installed — $(get_browser_location chrome)"
        _INSTALL_STATUS_chrome="existing"; return 0
    fi
    log_info "Installing Google Chrome on Windows ..."
    local installer="$TOOLS_HOME/chrome_installer.exe"
    if ! download_file "$CHROME_WIN_URL" "$installer" "Downloading Chrome installer ..."; then
        log_error "Chrome download failed"; _INSTALL_STATUS_chrome="download_failed"; return 1
    fi
    local wi; wi=$(convert_to_windows_path "$installer")
    log_info "Running Chrome installer silently ..."
    if command_exists timeout; then
        timeout $INSTALL_TIMEOUT cmd.exe /c "\"$wi\" /silent /install" >>"$LOG_FILE" 2>&1 || true
    else
        cmd.exe /c "\"$wi\" /silent /install" >>"$LOG_FILE" 2>&1 || true
    fi
    sleep 15
    if is_browser_installed "chrome"; then
        log_success "✓ Chrome installed — $(get_browser_location chrome)"; _INSTALL_STATUS_chrome="success"
    else
        log_error "Chrome install failed"; _INSTALL_STATUS_chrome="install_failed"
    fi
    rm -f "$installer" 2>/dev/null || true
}


################################################################################
# BROWSER INSTALLATION - MACOS
################################################################################
install_chrome_mac() {
    is_browser_installed "chrome" && log_success "✓ Chrome already installed" && _INSTALL_STATUS_chrome="existing" && return 0
    log_info "Installing Google Chrome on macOS ..."
    local dmg="$TOOLS_HOME/chrome.dmg"
    download_file "$CHROME_MAC_URL" "$dmg" "Downloading Chrome ..." || { _INSTALL_STATUS_chrome="download_failed"; return 1; }
    if hdiutil attach "$dmg" -nobrowse -quiet 2>>"$LOG_FILE"; then
        cp -R "/Volumes/Google Chrome/Google Chrome.app" "/Applications/" 2>>"$LOG_FILE" && \
            log_success "✓ Chrome installed" && _INSTALL_STATUS_chrome="success"
        hdiutil detach "/Volumes/Google Chrome" -quiet -force 2>>"$LOG_FILE" || true
    fi
    rm -f "$dmg" 2>/dev/null || true
}

install_firefox_mac() {
    is_browser_installed "firefox" && log_success "✓ Firefox already installed" && _INSTALL_STATUS_firefox="existing" && return 0
    log_info "Installing Mozilla Firefox on macOS ..."
    local dmg="$TOOLS_HOME/firefox.dmg"
    download_file "$FIREFOX_MAC_URL" "$dmg" "Downloading Firefox ..." || { _INSTALL_STATUS_firefox="download_failed"; return 1; }
    if hdiutil attach "$dmg" -nobrowse -quiet 2>>"$LOG_FILE"; then
        cp -R "/Volumes/Firefox/Firefox.app" "/Applications/" 2>>"$LOG_FILE" && \
            log_success "✓ Firefox installed" && _INSTALL_STATUS_firefox="success"
        hdiutil detach "/Volumes/Firefox" -quiet -force 2>>"$LOG_FILE" || true
    fi
    rm -f "$dmg" 2>/dev/null || true
}

################################################################################
# BROWSER INSTALLATION - LINUX
################################################################################
install_chrome_linux() {
    is_browser_installed "chrome" && log_success "✓ Chrome already installed" && _INSTALL_STATUS_chrome="existing" && return 0
    log_info "Installing Google Chrome on Linux ..."
    if [[ "$ARCH" == "x64" ]]; then
        local deb="$TOOLS_HOME/chrome.deb"
        download_file "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" \
            "$deb" "Downloading Chrome .deb ..." || { _INSTALL_STATUS_chrome="download_failed"; return 1; }
        command_exists sudo && sudo dpkg -i "$deb" >>"$LOG_FILE" 2>&1 || dpkg -i "$deb" >>"$LOG_FILE" 2>&1 || true
        command_exists sudo && sudo apt-get install -f -y >>"$LOG_FILE" 2>&1 || true
        rm -f "$deb" 2>/dev/null || true
        is_browser_installed "chrome" && log_success "✓ Chrome installed" && _INSTALL_STATUS_chrome="success" || \
            { log_error "Chrome install failed"; _INSTALL_STATUS_chrome="install_failed"; }
    else
        log_warning "Chrome not available for ARM Linux"; _INSTALL_STATUS_chrome="unsupported"
    fi
}

install_firefox_linux() {
    is_browser_installed "firefox" && log_success "✓ Firefox already installed" && _INSTALL_STATUS_firefox="existing" && return 0
    log_info "Installing Mozilla Firefox on Linux ..."
    if command_exists apt-get; then
        command_exists sudo && sudo apt-get update >>"$LOG_FILE" 2>&1 || true
        command_exists sudo && sudo apt-get install -y firefox >>"$LOG_FILE" 2>&1 || apt-get install -y firefox >>"$LOG_FILE" 2>&1 || true
    elif command_exists dnf; then
        command_exists sudo && sudo dnf install -y firefox >>"$LOG_FILE" 2>&1 || dnf install -y firefox >>"$LOG_FILE" 2>&1 || true
    elif command_exists yum; then
        command_exists sudo && sudo yum install -y firefox >>"$LOG_FILE" 2>&1 || yum install -y firefox >>"$LOG_FILE" 2>&1 || true
    else
        log_error "No supported package manager found"; _INSTALL_STATUS_firefox="unsupported"; return 1
    fi
    is_browser_installed "firefox" && log_success "✓ Firefox installed" && _INSTALL_STATUS_firefox="success" || \
        { log_error "Firefox install failed"; _INSTALL_STATUS_firefox="install_failed"; }
}

################################################################################
# BROWSER INSTALLATION ORCHESTRATOR
################################################################################
install_browsers() {
    log_section "BROWSER INSTALLATION"
    case "$OS" in
        windows) install_chrome_windows || true; echo "" >&2;
                 is_browser_installed "edge" && log_success "✓ Microsoft Edge detected" ;;
        mac)     install_chrome_mac || true; echo "" >&2; install_firefox_mac || true
                 is_browser_installed "safari" && log_success "✓ Safari detected"
                 is_browser_installed "edge"   && log_success "✓ Microsoft Edge detected" ;;
        linux)   install_chrome_linux || true; echo "" >&2; install_firefox_linux || true
                 is_browser_installed "chromium" && log_success "✓ Chromium detected" ;;
    esac
    echo "" >&2
    log_info "Browser Summary:"
    for browser in chrome firefox; do
        _status=$(eval "echo \$_INSTALL_STATUS_${browser}")
        case "$_status" in
            success)  log_success "  ✓ $browser: Installed" ;;
            existing) [[ "$OS" == "windows" ]] && log_success "  ✓ $browser: $(get_browser_location $browser)" \
                          || log_success "  ✓ $browser: Already installed" ;;
            failed|download_failed|install_failed) log_warning "  ✗ $browser: Failed ($_status)" ;;
            unsupported) log_info "  - $browser: Not supported on this platform" ;;
        esac
    done
}

################################################################################
# REPOSITORY CLONING
################################################################################
clone_repository() {
    log_section "AUTOMATION FRAMEWORK REPOSITORY"
    log_info "Repository URL   : $REPO_URL"
    log_info "Clone destination: $FRAMEWORK_DIR"

    if [[ -d "$FRAMEWORK_DIR/.git" ]]; then
        log_success "✓ Repository already exists at $FRAMEWORK_DIR"
        _INSTALL_STATUS_repository="existing"; return 0
    fi

    if [[ -d "$FRAMEWORK_DIR" ]] && [[ -n "$(ls -A "$FRAMEWORK_DIR" 2>/dev/null)" ]]; then
        log_warning "Directory not empty — cloning into: $FRAMEWORK_DIR/automation-agent-framework"
        FRAMEWORK_DIR="$FRAMEWORK_DIR/automation-agent-framework"
        mkdir -p "$FRAMEWORK_DIR" 2>/dev/null || true
    fi

    log_info "Cloning repository, please wait ..."
    if git clone "$REPO_URL" "$FRAMEWORK_DIR" 2>&1 | tee -a "$LOG_FILE" >&2; then
        log_success "✓ Repository cloned to: $FRAMEWORK_DIR"
        _INSTALL_STATUS_repository="success"; return 0
    else
        log_error "Repository cloning failed"
        log_info "Manual: git clone $REPO_URL $FRAMEWORK_DIR"
        _INSTALL_STATUS_repository="failed"; return 1
    fi
}

################################################################################
# FINAL SUMMARY
################################################################################
print_summary() {
    log_section "INSTALLATION SUMMARY"
    echo "" >&2; log_success "✓ SETUP PROCESS COMPLETED"; echo "" >&2
    log_info "Installation Results:"

    case "${_INSTALL_STATUS_java}"   in
        success)     log_success "  ✓ Java JDK $JAVA_VERSION     : Installed"          ;;
        existing)    log_success "  ✓ Java JDK $JAVA_VERSION     : Already installed"  ;;
        failed)      log_error   "  ✗ Java JDK $JAVA_VERSION     : Failed"             ;;
        unsupported) log_warning "  - Java JDK $JAVA_VERSION     : Unsupported"        ;;
    esac
    case "${_INSTALL_STATUS_maven}"  in
        success)     log_success "  ✓ Maven $MAVEN_VERSION        : Installed"          ;;
        existing)    log_success "  ✓ Maven $MAVEN_VERSION        : Already installed"  ;;
        failed)      log_error   "  ✗ Maven $MAVEN_VERSION        : Failed"             ;;
        unsupported) log_warning "  - Maven $MAVEN_VERSION        : Unsupported"        ;;
    esac

    if [[ "$SKIP_BROWSERS" == false ]]; then
        for browser in chrome firefox; do
            _bstatus=$(eval "echo \$_INSTALL_STATUS_${browser}")
            case "$_bstatus" in
                success)  log_success "  ✓ $browser: Installed" ;;
                existing) [[ "$OS" == "windows" ]] && log_success "  ✓ $browser: $(get_browser_location $browser)" \
                              || log_success "  ✓ $browser: Already installed" ;;
                failed|download_failed|install_failed) log_warning "  ✗ $browser: $_bstatus" ;;
                unsupported) log_info "  - $browser: Not supported" ;;
            esac
        done
    fi



    echo "" >&2
    log_warning "NEXT STEPS:"
    if [[ "$OS" == "windows" ]]; then
        log_info "  Option A — Apply in THIS window immediately:"
        log_info "             source ~/.bashrc"
        log_info ""
        log_info "  Option B — Open a NEW Git Bash window"
        log_info "             (auto-loads via ~/.bash_profile → ~/.bashrc)"
        log_info ""
        log_info "  NOTE: JAVA_HOME, MAVEN_HOME, PATH also written to Windows"
        log_info "        User registry via PowerShell + setx (3 persistence layers)"
    else
        log_info "  1. Reload shell: source ~/.bashrc  (or source ~/.zshrc)"
        if [[ "$OS" == "mac" ]]; then
            log_info "     (zsh login shell also reads ~/.zprofile — already updated)"
        fi
    fi
    log_info "  2. Verify:"
    log_info "       java -version  |  mvn -version"
    log_info "       echo \$JAVA_HOME  |  echo \$MAVEN_HOME  |  echo \$AUTOMATION_PATH"

    echo "" >&2
    log_info "Paths:"
    log_info "  • Tools           : $TOOLS_HOME"
    log_info "  • AUTOMATION_PATH : $AUTOMATION_PATH"
    [[ -d "$FRAMEWORK_DIR" ]] && log_info "  • Framework       : $FRAMEWORK_DIR"
    log_info "  • Log file        : $LOG_FILE"
    echo "" >&2
    log_success "✓ Setup completed successfully!"
    echo "" >&2
}

################################################################################
# MAIN EXECUTION
################################################################################
main() {
    echo "Automation Environment Setup - $(date)" > "$LOG_FILE"
    echo -e "${BOLD}${CYAN}" >&2
    echo "================================================================================" >&2
    echo "  CROSS-PLATFORM AUTOMATION ENVIRONMENT SETUP"                                   >&2
    echo "  Version  : $SCRIPT_VERSION"                                                     >&2
    echo "  Platform : Detects Admin & User-Level Installs"                                 >&2
    echo "================================================================================" >&2
    echo -e "${NC}" >&2

    while [[ $# -gt 0 ]]; do
        case "$1" in
            --skip-browsers)  SKIP_BROWSERS=true; shift ;;
            --skip-git-clone) SKIP_GIT_CLONE=true; shift ;;
            --path)
                if [[ -n "${2:-}" ]]; then
                    AUTOMATION_PATH=$(normalize_input_path "$2")
                    FRAMEWORK_DIR="$AUTOMATION_PATH"
                    log_info "Resolved --path: '$2' → '$AUTOMATION_PATH'"
                    shift 2
                else
                    log_warning "--path flag provided but no value given"
                    shift
                fi
                ;;
            --help|-h)
                echo "Usage: $0 [OPTIONS]"
                echo "  --skip-browsers    Skip browser installation"
                echo "  --skip-git-clone   Skip repository cloning"
                echo "  --path <dir>       Set installation path"
                echo "  --help, -h         Show help"
                exit 0 ;;
            *) shift ;;
        esac
    done

    mkdir -p "$TOOLS_HOME" 2>/dev/null || true

    detect_platform                    # Step 1

    if [[ -z "$AUTOMATION_PATH" ]]; then
        prompt_installation_path       # Step 2a — interactive
    else
        mkdir -p "$AUTOMATION_PATH" 2>/dev/null || true
        [[ "$OS" == "windows" ]] && set_windows_env_variable "AUTOMATION_PATH" "$AUTOMATION_PATH"
        update_profile "AUTOMATION_PATH" "$AUTOMATION_PATH"
        export AUTOMATION_PATH
        log_success "✓ AUTOMATION_PATH = $AUTOMATION_PATH (from --path argument)"
    fi

    verify_dependencies || true        # Step 3
    install_java        || true        # Step 4 — downloads & configures JDK 17
    install_maven       || true        # Step 5

#    if validate_git; then              # Step 6
#        [[ "$SKIP_GIT_CLONE" == false ]] && clone_repository || true
#    fi

    [[ "$SKIP_BROWSERS" == false ]] && install_browsers || true   # Step 7

    print_summary                      # Step 8
}

main "$@"