#!/bin/bash

# ==============================================================================
#  Hadoop Handler — Single-Node Cluster Control Panel (Linux & macOS)
#  Developer: Aditya Pidurkar (github.com/itsadityapidurkar)
# ==============================================================================

CURRENT_VERSION="1.2.0"

# Colors for terminal output
RED='\033[0;31m'
BRED='\033[1;31m'
GREEN='\033[0;32m'
BGREEN='\033[1;32m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BCYAN='\033[1;36m'
YELLOW='\033[1;33m'
GRAY='\033[90m'
NC='\033[0m' # No Color

DIVIDER="${GRAY}─────────────────────────────────────────────────────────────────${NC}"

# Detect OS
OS_NAME=$(uname -s)

# Portable symlink resolution to find original install directory
TARGET_FILE="${BASH_SOURCE[0]}"
while [ -h "$TARGET_FILE" ]; do
    DIR="$(dirname "$TARGET_FILE")"
    TARGET_FILE="$(readlink "$TARGET_FILE")"
    [[ "$TARGET_FILE" != /* ]] && TARGET_FILE="$DIR/$TARGET_FILE"
done
SCRIPT_DIR="$(cd -P "$(dirname "$TARGET_FILE")" && pwd)"

# Send native desktop notification
send_notification() {
    local title="$1"
    local message="$2"
    if [ "$OS_NAME" = "Linux" ] && command -v notify-send >/dev/null 2>&1; then
        notify-send "$title" "$message" 2>/dev/null || true
    elif [ "$OS_NAME" = "Darwin" ]; then
        osascript -e "display notification \"$message\" with title \"$title\"" 2>/dev/null || true
    fi
}

# Resolve download URL for any given Hadoop version (mirrors with archive fallback)
resolve_hadoop_url() {
    local ver="$1"
    local tar_name="hadoop-${ver}.tar.gz"
    local mirror_url="https://downloads.apache.org/hadoop/common/hadoop-${ver}/${tar_name}"
    local archive_url="https://archive.apache.org/dist/hadoop/common/hadoop-${ver}/${tar_name}"

    if curl -s --head --max-time 3 "$mirror_url" 2>/dev/null | grep -E "200|302" >/dev/null; then
        echo "$mirror_url"
    else
        echo "$archive_url"
    fi
}

# Smooth download progress with Python or curl fallback
download_file() {
    local url="$1"
    local dest="$2"
    local title="${3:-Downloading}"

    if command -v python3 >/dev/null 2>&1; then
        python3 - << EOF
import os, sys, time, urllib.request

url = "$url"
dest = "$dest"
title = "$title"

headers = {'User-Agent': 'Hadoop-Handler/$CURRENT_VERSION'}
resume_byte_pos = 0
if os.path.exists(dest):
    resume_byte_pos = os.path.getsize(dest)

req = urllib.request.Request(url, headers=headers)
if resume_byte_pos > 0:
    req.add_header("Range", f"bytes={resume_byte_pos}-")

try:
    with urllib.request.urlopen(req, timeout=30) as resp:
        content_length = resp.headers.get('Content-Length')
        if resp.status == 206:
            total_size = resume_byte_pos + int(content_length) if content_length else 0
            mode = 'ab'
            downloaded = resume_byte_pos
        else:
            total_size = int(content_length) if content_length else 0
            mode = 'wb'
            downloaded = 0

        start_time = time.time()
        chunk_size = 131072
        bar_width = 24

        print(f"        {title}...")
        with open(dest, mode) as f:
            while True:
                chunk = resp.read(chunk_size)
                if not chunk:
                    break
                f.write(chunk)
                downloaded += len(chunk)
                elapsed = time.time() - start_time
                speed = (downloaded - resume_byte_pos) / elapsed if elapsed > 0 else 0

                if total_size > 0:
                    pct = min(100.0, (downloaded / total_size) * 100)
                    filled = int(bar_width * downloaded // total_size)
                    bar = '█' * filled + '░' * (bar_width - filled)
                    eta = (total_size - downloaded) / speed if speed > 0 else 0
                    eta_str = f"{int(eta // 60):02d}:{int(eta % 60):02d}"
                    sys.stdout.write(f"\r        [{bar}] {pct:5.1f}% ({downloaded/(1024*1024):.1f}/{total_size/(1024*1024):.1f} MB) {speed/(1024*1024):.1f} MB/s ETA {eta_str}")
                else:
                    sys.stdout.write(f"\r        Downloaded: {downloaded/(1024*1024):.1f} MB ({speed/(1024*1024):.1f} MB/s)")
                sys.stdout.flush()
        print()
    sys.exit(0)
except Exception as e:
    sys.stderr.write(f"\n        [!] Python download interrupted ({e}), falling back to curl...\n")
    sys.exit(1)
EOF
        if [ $? -eq 0 ] && [ -s "$dest" ]; then
            return 0
        fi
    fi

    # Fallback to curl with progress bar
    if command -v curl >/dev/null 2>&1; then
        echo -e "        Downloading via curl (progress bar enabled)..."
        curl -# -L -C - -o "$dest" "$url"
        return $?
    elif command -v wget >/dev/null 2>&1; then
        wget --progress=bar:force -c -O "$dest" "$url"
        return $?
    else
        echo -e "  ${RED}[!] Neither python3, curl, nor wget found.${NC}"
        return 1
    fi
}

# Check PyPI / GitHub for newer releases and display non-intrusive banner
check_version_banner() {
    local cache_file="$HOME/.hadoop-handler/.version_cache"
    local now=$(date +%s)
    local last_check=0

    mkdir -p "$HOME/.hadoop-handler" 2>/dev/null || true
    if [ -f "$cache_file" ]; then
        last_check=$(stat -c %Y "$cache_file" 2>/dev/null || stat -f %m "$cache_file" 2>/dev/null || echo 0)
    fi

    if [ $((now - last_check)) -gt 43200 ]; then
        (
            local latest=$(curl -s --max-time 1.5 https://api.github.com/repos/itsadityapidurkar/hadoop-handler/releases/latest 2>/dev/null | grep '"tag_name":' | sed -E 's/.*"v?([^"]+)".*/\1/' || echo "")
            if [ -n "$latest" ]; then
                echo "$latest" > "$cache_file"
            else
                latest=$(curl -s --max-time 1.5 https://pypi.org/pypi/hadoop-handler/json 2>/dev/null | grep -o '"version":"[^"]*"' | head -n 1 | cut -d'"' -f4 || echo "")
                [ -n "$latest" ] && echo "$latest" > "$cache_file"
            fi
        ) 2>/dev/null &
    fi

    if [ -f "$cache_file" ]; then
        local remote_ver=$(cat "$cache_file" 2>/dev/null | tr -d '[:space:]')
        if [ -n "$remote_ver" ] && [ "$remote_ver" != "$CURRENT_VERSION" ]; then
            echo -e "  ${YELLOW}* Note: Update available: ${CURRENT_VERSION} -> ${remote_ver}.${NC}"
            echo -e "    Run ${CYAN}hadoop-handler update${NC} to upgrade."
            echo -e "$DIVIDER"
        fi
    fi
}

# Load environment variables dynamically within the script execution context
load_env() {
    if [ -z "$HADOOP_HOME" ]; then
        if [ -d "/opt/hadoop" ]; then
            export HADOOP_HOME="/opt/hadoop"
        elif [ -d "/Users/Shared/hadoop" ]; then
            export HADOOP_HOME="/Users/Shared/hadoop"
        elif [ -d "$HOME/hadoop" ]; then
            export HADOOP_HOME="$HOME/hadoop"
        fi
    fi
    if [ -n "$HADOOP_HOME" ]; then
        export HADOOP_CONF_DIR="$HADOOP_HOME/etc/hadoop"
        export PATH="$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin"
        # Detect Java Home if not set
        if [ -z "$JAVA_HOME" ]; then
            if [ "$OS_NAME" = "Linux" ]; then
                if command -v java >/dev/null 2>&1; then
                    export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
                fi
            elif [ "$OS_NAME" = "Darwin" ]; then
                if command -v java >/dev/null 2>&1; then
                    export JAVA_HOME=$(/usr/libexec/java_home 2>/dev/null || echo "")
                fi
            fi
        fi
    fi
}

pause_screen() {
    echo -e "\n$DIVIDER"
    echo -ne "  ${YELLOW}Press [Enter] to return to the main menu...${NC}"
    read -r
}

# ==============================================================================
#  JAVA DETECTION, SWITCHING & COMPATIBILITY CHECKER
# ==============================================================================

# Scan system for all installed JVMs
detect_installed_javas() {
    local seen_paths=()
    local jvms=()

    add_jvm() {
        local jpath="$1"
        [ -z "$jpath" ] && return
        if [ -d "$jpath" ] && [ -x "$jpath/bin/java" ]; then
            local real_path=$(cd -P "$jpath" 2>/dev/null && pwd)
            for s in "${seen_paths[@]}"; do
                [ "$s" = "$real_path" ] && return
            done
            seen_paths+=("$real_path")
            local ver_str=$("$real_path/bin/java" -version 2>&1 | head -n 1 | sed -E 's/.*version "([^"]+)".*/\1/')
            local major_ver=$(echo "$ver_str" | cut -d'.' -f1)
            [ "$major_ver" = "1" ] && major_ver=$(echo "$ver_str" | cut -d'.' -f2)
            jvms+=("${major_ver}|${ver_str}|${real_path}")
        fi
    }

    [ -n "$JAVA_HOME" ] && add_jvm "$JAVA_HOME"

    if command -v java >/dev/null 2>&1; then
        local bin_j=$(readlink -f "$(which java)" 2>/dev/null || which java)
        add_jvm "$(dirname "$(dirname "$bin_j")")"
    fi

    if [ -d "/usr/lib/jvm" ]; then
        for d in /usr/lib/jvm/*; do
            [ -d "$d" ] && add_jvm "$d"
        done
    fi

    if [ -d "/Library/Java/JavaVirtualMachines" ]; then
        for d in /Library/Java/JavaVirtualMachines/*/Contents/Home; do
            [ -d "$d" ] && add_jvm "$d"
        done
    fi

    for item in "${jvms[@]}"; do
        echo "$item"
    done
}

# Manage Java runtimes (list, switch, use)
manage_java() {
    local action="$1"
    local arg="$2"

    local jvm_records=()
    while IFS= read -r line; do
        [ -n "$line" ] && jvm_records+=("$line")
    done < <(detect_installed_javas)

    if [ "$action" = "list" ]; then
        clear
        echo -e "$DIVIDER"
        echo -e "  ${BCYAN}ACTION: Detected Java Runtimes (JVMs)${NC}"
        echo -e "$DIVIDER\n"
        printf "  %-7s %-12s %-45s %s\n" "INDEX" "VERSION" "PATH" "ACTIVE"
        echo -e "  -----------------------------------------------------------------"
        for idx in "${!jvm_records[@]}"; do
            IFS="|" read -r major ver path <<< "${jvm_records[$idx]}"
            local active=" "
            if [ "$path" = "$JAVA_HOME" ]; then
                active="${GREEN}[ACTIVE]${NC}"
            fi
            printf "  [%2d]    %-12s %-45s %b\n" "$((idx + 1))" "Java $major" "$path" "$active"
        done
        echo -e "$DIVIDER"
        return 0
    fi

    # Switch / Use action
    local chosen_path=""
    if [ -n "$arg" ]; then
        if [[ "$arg" =~ ^[0-9]+$ ]] && [ "$arg" -le "${#jvm_records[@]}" ] && [ "$arg" -gt 0 ]; then
            IFS="|" read -r _ _ chosen_path <<< "${jvm_records[$((arg - 1))]}"
        elif [ -d "$arg" ] && [ -x "$arg/bin/java" ]; then
            chosen_path="$arg"
        else
            for item in "${jvm_records[@]}"; do
                IFS="|" read -r major ver path <<< "$item"
                if [ "$major" = "$arg" ]; then
                    chosen_path="$path"
                    break
                fi
            done
        fi
    fi

    if [ -z "$chosen_path" ]; then
        clear
        echo -e "$DIVIDER"
        echo -e "  ${BCYAN}ACTION: Switch Java Runtime for Hadoop${NC}"
        echo -e "$DIVIDER\n"
        echo -e "  Available Java Runtimes on this system:"
        for idx in "${!jvm_records[@]}"; do
            IFS="|" read -r major ver path <<< "${jvm_records[$idx]}"
            local mark=" "
            [ "$path" = "$JAVA_HOME" ] && mark="${GREEN}[ACTIVE]${NC}"
            printf "    [ %d ] Java %-2s (%s) %b\n" "$((idx + 1))" "$major" "$path" "$mark"
        done
        echo -e "    [ 0 ] Cancel"
        echo -e "$DIVIDER"
        read -p "  Select Java runtime to use [1-${#jvm_records[@]}]: " pick
        if [[ "$pick" =~ ^[0-9]+$ ]] && [ "$pick" -gt 0 ] && [ "$pick" -le "${#jvm_records[@]}" ]; then
            IFS="|" read -r _ _ chosen_path <<< "${jvm_records[$((pick - 1))]}"
        else
            echo -e "  Operation cancelled."
            return 0
        fi
    fi

    if [ -n "$chosen_path" ] && [ -d "$chosen_path" ]; then
        export JAVA_HOME="$chosen_path"
        echo -e "  [+] Setting JAVA_HOME=${GREEN}${chosen_path}${NC}"

        if [ -n "$HADOOP_HOME" ] && [ -f "${HADOOP_HOME}/etc/hadoop/hadoop-env.sh" ]; then
            sed -i.bak "s|^export JAVA_HOME=.*|export JAVA_HOME=${chosen_path}|g" "${HADOOP_HOME}/etc/hadoop/hadoop-env.sh" 2>/dev/null || \
            sed -i '' "s|^export JAVA_HOME=.*|export JAVA_HOME=${chosen_path}|g" "${HADOOP_HOME}/etc/hadoop/hadoop-env.sh" 2>/dev/null
            rm -f "${HADOOP_HOME}/etc/hadoop/hadoop-env.sh.bak"
            echo -e "  [+] Updated ${HADOOP_HOME}/etc/hadoop/hadoop-env.sh"
        fi

        local prof="$HOME/.bashrc"
        [[ "$SHELL" == */zsh ]] && prof="$HOME/.zshrc"
        if [ -f "$prof" ]; then
            sed -i.bak "s|^export JAVA_HOME=.*|export JAVA_HOME=\"${chosen_path}\"|g" "$prof" 2>/dev/null || \
            sed -i '' "s|^export JAVA_HOME=.*|export JAVA_HOME=\"${chosen_path}\"|g" "$prof" 2>/dev/null
            rm -f "${prof}.bak"
            echo -e "  [+] Updated ${prof}"
        fi

        echo -e "\n  ${GREEN}[✓] Active Java runtime switched successfully!${NC}"
        send_notification "Hadoop Handler" "Switched Hadoop Java runtime to ${chosen_path}."

        if command -v hadoop >/dev/null 2>&1; then
            echo ""
            check_compatibility "" ""
        fi
    fi
}

# Hadoop <-> Java Compatibility Matrix Checker
check_compatibility() {
    local hadoop_v="$1"
    local java_v="$2"

    if [ -z "$hadoop_v" ]; then
        if command -v hadoop >/dev/null 2>&1; then
            hadoop_v=$(hadoop version 2>/dev/null | head -n 1 | awk '{print $2}')
        else
            hadoop_v="3.4.2"
        fi
    fi

    if [ -z "$java_v" ]; then
        if [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ]; then
            local j_str=$("$JAVA_HOME/bin/java" -version 2>&1 | head -n 1)
            java_v=$(echo "$j_str" | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f1)
            [ "$java_v" = "1" ] && java_v=$(echo "$j_str" | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f2)
        elif command -v java >/dev/null 2>&1; then
            local j_str=$(java -version 2>&1 | head -n 1)
            java_v=$(echo "$j_str" | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f1)
            [ "$java_v" = "1" ] && java_v=$(echo "$j_str" | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f2)
        else
            java_v="unknown"
        fi
    fi

    local h_major=$(echo "$hadoop_v" | cut -d'.' -f1)
    local h_minor=$(echo "$hadoop_v" | cut -d'.' -f2)
    local j_major=$(echo "$java_v" | cut -d'.' -f1)
    [ "$j_major" = "1" ] && j_major=$(echo "$java_v" | cut -d'.' -f2)

    echo -e "  Checking compatibility: Hadoop ${CYAN}${hadoop_v}${NC} <-> Java ${CYAN}${java_v}${NC}..."

    local compatible=true
    local reason=""
    local recommended=""

    if [ "$h_major" -ge 3 ] && [ "$h_minor" -ge 4 ]; then
        if [ "$j_major" -eq 8 ] || [ "$j_major" -eq 11 ] || [ "$j_major" -eq 17 ] || [ "$j_major" -eq 21 ]; then
            compatible=true
        elif [ "$j_major" -gt 21 ]; then
            compatible=false
            reason="Java $j_major is newer than officially validated LTS runtimes."
            recommended="Java 11, 17, or 21"
        else
            compatible=false
            reason="Hadoop 3.4+ requires at least Java 8."
            recommended="Java 11, 17, or 21"
        fi
    elif [ "$h_major" -eq 3 ] && [ "$h_minor" -eq 3 ]; then
        if [ "$j_major" -eq 8 ] || [ "$j_major" -eq 11 ] || [ "$j_major" -eq 17 ]; then
            compatible=true
        else
            compatible=false
            reason="Hadoop 3.3.x does not support Java $j_major (fails on Java 21+)."
            recommended="Java 8, 11, or 17"
        fi
    elif [ "$h_major" -eq 3 ] && [ "$h_minor" -le 2 ]; then
        if [ "$j_major" -eq 8 ] || [ "$j_major" -eq 11 ]; then
            compatible=true
        else
            compatible=false
            reason="Hadoop 3.0-3.2 fails on Java 17+ due to JVM module encapsulation (JEP 396/403)."
            recommended="Java 8 or Java 11"
        fi
    elif [ "$h_major" -eq 2 ]; then
        if [ "$j_major" -eq 7 ] || [ "$j_major" -eq 8 ]; then
            compatible=true
        else
            compatible=false
            reason="Hadoop 2.x only supports Java 7 or Java 8."
            recommended="Java 8"
        fi
    fi

    if [ "$compatible" = "true" ]; then
        echo -e "  ${GREEN}[✓] Compatible: Hadoop ${hadoop_v} is officially verified on Java ${java_v}.${NC}"
        return 0
    else
        echo -e "  ${RED}[!] Incompatibility Detected: ${reason}${NC}"
        echo -e "      ${YELLOW}Recommended runtime for Hadoop ${hadoop_v}: ${recommended}.${NC}"
        echo -e "      ${GRAY}Tip: Use 'hadoop-handler java switch' to select a compatible JVM.${NC}"
        return 1
    fi
}

# ==============================================================================
#  INSTALLATION & IN-PLACE UPGRADE / DOWNGRADE
# ==============================================================================

# 1. Install Hadoop with Dynamic Version Selector
install_hadoop() {
    clear
    load_env
    echo -e "$DIVIDER"
    echo -e "  ${BCYAN}ACTION: Installing Apache Hadoop (Dynamic Version Selector)${NC}"
    echo -e "$DIVIDER\n"

    local selected_ver="$1"
    if [ "$selected_ver" = "--version" ]; then
        selected_ver="$2"
    fi

    if [ -z "$selected_ver" ]; then
        echo -e "  Select Hadoop Version to Install:"
        echo -e "    1. 3.4.2 (Latest Stable, Java 8/11/17/21) [Default]"
        echo -e "    2. 3.4.1 (Java 8/11/17/21)"
        echo -e "    3. 3.3.6 (Production LTS, Java 8/11/17)"
        echo -e "    4. 3.3.5 (Java 8/11)"
        echo -e "    5. 3.2.4 (Legacy, Java 8/11)"
        echo -e "    6. Custom version"
        read -p "  Enter choice [1-6, default 1]: " vchoice
        case "$vchoice" in
            2) selected_ver="3.4.1" ;;
            3) selected_ver="3.3.6" ;;
            4) selected_ver="3.3.5" ;;
            5) selected_ver="3.2.4" ;;
            6) read -p "  Enter version string (e.g. 3.4.0): " selected_ver ;;
            *) selected_ver="3.4.2" ;;
        esac
    fi

    [ -z "$selected_ver" ] && selected_ver="3.4.2"
    echo -e "\n  Target Hadoop Version: ${GREEN}${selected_ver}${NC}"

    # Check / Detect Java Compatibility
    echo -e "\n  ${GRAY}[1/8]${NC} Validating Java runtime..."
    local detected_java_home=""
    if [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ]; then
        detected_java_home="$JAVA_HOME"
    elif command -v java >/dev/null 2>&1; then
        detected_java_home=$(dirname $(dirname $(readlink -f $(which java) 2>/dev/null || which java)))
    fi

    if [ -n "$detected_java_home" ]; then
        local j_cur=$("$detected_java_home/bin/java" -version 2>&1 | head -n 1 | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f1)
        [ "$j_cur" = "1" ] && j_cur=$("$detected_java_home/bin/java" -version 2>&1 | head -n 1 | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f2)
        echo -e "        Active Java: ${CYAN}Java ${j_cur}${NC} (${detected_java_home})"
        
        check_compatibility "$selected_ver" "$j_cur" || {
            echo -e "\n  ${YELLOW}[!] Would you like to select an alternative installed Java? (y/N)${NC}"
            read -p "  > " switch_j
            if [[ "$switch_j" =~ ^[Yy]$ ]]; then
                manage_java "switch"
                load_env
                detected_java_home="$JAVA_HOME"
            fi
        }
    else
        echo -e "        ${YELLOW}[!] No Java detected. Attempting to install OpenJDK 21...${NC}"
        if [ "$OS_NAME" = "Linux" ]; then
            if command -v apt-get >/dev/null 2>&1; then
                sudo apt-get update && sudo apt-get install -y openjdk-21-jdk || return 1
            elif command -v dnf >/dev/null 2>&1; then
                sudo dnf install -y java-21-openjdk-devel || return 1
            elif command -v pacman >/dev/null 2>&1; then
                sudo pacman -S --noconfirm jre21-openjdk jdk21-openjdk || return 1
            fi
            detected_java_home=$(dirname $(dirname $(readlink -f $(which java))))
        elif [ "$OS_NAME" = "Darwin" ]; then
            brew install openjdk@21 || return 1
            detected_java_home=$(/usr/libexec/java_home -v 21 2>/dev/null || echo "")
        fi
    fi

    [ -z "$detected_java_home" ] && detected_java_home="/usr/lib/jvm/default-java"

    # Target Locations
    HADOOP_DEST="/opt/hadoop"
    HADOOP_DATA_DIR="/opt/hadoop_data"
    HADOOP_TMP_DIR="/opt/hadoop_tmp"
    HADOOP_TAR="hadoop-${selected_ver}.tar.gz"
    DOWNLOAD_URL=$(resolve_hadoop_url "$selected_ver")

    if [ "$OS_NAME" = "Darwin" ]; then
        if [[ "$HOME" == *" "* ]]; then
            HADOOP_DEST="/Users/Shared/hadoop"
            HADOOP_DATA_DIR="/Users/Shared/hadoop_data"
            HADOOP_TMP_DIR="/Users/Shared/hadoop_tmp"
        else
            HADOOP_DEST="$HOME/hadoop"
            HADOOP_DATA_DIR="$HOME/hadoopdata"
            HADOOP_TMP_DIR="$HOME/hadooptmp"
        fi
    fi

    # Create Directories
    echo -e "\n  ${GRAY}[2/8]${NC} Creating required system directories..."
    mkdir -p ~/Downloads
    if [ "$OS_NAME" = "Linux" ] && [[ "$HOME" == *" "* ]]; then
        sudo mkdir -p "${HADOOP_DATA_DIR}/namenode" "${HADOOP_DATA_DIR}/datanode" "${HADOOP_TMP_DIR}"
        sudo chown -R $USER:$USER "${HADOOP_DATA_DIR}" "${HADOOP_TMP_DIR}"
    else
        mkdir -p "${HADOOP_DATA_DIR}/namenode" "${HADOOP_DATA_DIR}/datanode" "${HADOOP_TMP_DIR}"
    fi

    # Download Hadoop tarball with smooth progress
    echo -e "\n  ${GRAY}[3/8]${NC} Retrieving Apache Hadoop ${selected_ver} tarball..."
    if [ -f "$HOME/Downloads/${HADOOP_TAR}" ]; then
        echo -e "        ${HADOOP_TAR} already cached in ~/Downloads. Skipping download."
    else
        download_file "${DOWNLOAD_URL}" "$HOME/Downloads/${HADOOP_TAR}" "Retrieving Apache Hadoop ${selected_ver}" || {
            echo -e "  ${RED}[!] Download failed for ${selected_ver}.${NC}"
            rm -f "$HOME/Downloads/${HADOOP_TAR}"
            return 1
        }
        send_notification "Hadoop Handler" "Apache Hadoop ${selected_ver} downloaded."
    fi

    # Extract and Relocate
    echo -e "\n  ${GRAY}[4/8]${NC} Extracting and relocating binaries..."
    if [ "$OS_NAME" = "Linux" ]; then
        [ -d "${HADOOP_DEST}" ] && sudo rm -rf "${HADOOP_DEST}"
        sudo tar -xzf "$HOME/Downloads/${HADOOP_TAR}" -C /opt || { echo -e "  ${RED}[!] Extraction failed.${NC}"; return 1; }
        sudo mv "/opt/hadoop-${selected_ver}" "${HADOOP_DEST}"
        sudo chown -R $USER:$USER "${HADOOP_DEST}"
    else
        [ -d "${HADOOP_DEST}" ] && rm -rf "${HADOOP_DEST}"
        if [[ "$HOME" == *" "* ]]; then
            tar -xzf "$HOME/Downloads/${HADOOP_TAR}" -C /Users/Shared || { echo -e "  ${RED}[!] Extraction failed.${NC}"; return 1; }
            mv "/Users/Shared/hadoop-${selected_ver}" "${HADOOP_DEST}"
        else
            tar -xzf "$HOME/Downloads/${HADOOP_TAR}" -C "$HOME/" || { echo -e "  ${RED}[!] Extraction failed.${NC}"; return 1; }
            mv "$HOME/hadoop-${selected_ver}" "${HADOOP_DEST}"
        fi
    fi
    echo -e "        Extraction completed successfully."
    send_notification "Hadoop Handler" "Apache Hadoop ${selected_ver} binaries extracted."

    # Configure SSH
    echo -e "\n  ${GRAY}[5/8]${NC} Configuring passwordless SSH keys..."
    if [ ! -f ~/.ssh/id_rsa ]; then
        ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" || return 1
    fi
    touch ~/.ssh/authorized_keys
    if ! grep -q "$(cat ~/.ssh/id_rsa.pub)" ~/.ssh/authorized_keys 2>/dev/null; then
        cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
    fi
    chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
    if ! ssh-keygen -F localhost >/dev/null 2>&1; then
        ssh-keyscan -H localhost >> ~/.ssh/known_hosts 2>/dev/null
    fi

    # Configure Environment Variables
    echo -e "\n  ${GRAY}[6/8]${NC} Registering path variables in shell configuration..."
    SHELL_CONFIG=""
    [[ "$SHELL" == */zsh ]] && SHELL_CONFIG="$HOME/.zshrc" || SHELL_CONFIG="$HOME/.bashrc"

    ENV_MARKER="# --- HADOOP HANDLER ENVIRONMENT VARIABLES ---"
    if grep -q "$ENV_MARKER" "${SHELL_CONFIG}" 2>/dev/null; then
        echo -e "        Environment variables already present in ${SHELL_CONFIG}."
    else
        cat << EOF >> "${SHELL_CONFIG}"

$ENV_MARKER
export JAVA_HOME="${detected_java_home}"
export HADOOP_HOME="${HADOOP_DEST}"
export HADOOP_CONF_DIR="\${HADOOP_HOME}/etc/hadoop"
export HADOOP_COMMON_HOME="\${HADOOP_HOME}"
export HADOOP_HDFS_HOME="\${HADOOP_HOME}"
export HADOOP_MAPRED_HOME="\${HADOOP_HOME}"
export YARN_HOME="\${HADOOP_HOME}"
export HADOOP_COMMON_LIB_NATIVE_DIR="\${HADOOP_HOME}/lib/native"
export PATH="\$PATH:\$HADOOP_HOME/bin:\$HADOOP_HOME/sbin"
EOF
        echo -e "        Variables appended to ${SHELL_CONFIG}."
    fi

    # Configure XML Files
    echo -e "\n  ${GRAY}[7/8]${NC} Building cluster configuration files..."
    CONF_DIR="${HADOOP_DEST}/etc/hadoop"
    LOCAL_CONF_DIR="${HADOOP_HANDLER_CONF_DIR:-${SCRIPT_DIR}/configs}"

    if [ -d "$LOCAL_CONF_DIR" ]; then
        echo -e "        Loading XML templates from local configs directory..."
        cp "${LOCAL_CONF_DIR}/core-site.xml" "${CONF_DIR}/"
        cp "${LOCAL_CONF_DIR}/hdfs-site.xml" "${CONF_DIR}/"
        cp "${LOCAL_CONF_DIR}/mapred-site.xml" "${CONF_DIR}/"
        cp "${LOCAL_CONF_DIR}/yarn-site.xml" "${CONF_DIR}/"
        cp "${LOCAL_CONF_DIR}/workers" "${CONF_DIR}/"
        
        sed -i.bak "s|/home/YOUR_USERNAME/hadooptmp|${HADOOP_TMP_DIR}|g" "${CONF_DIR}/core-site.xml" 2>/dev/null || \
        sed -i "" "s|/home/YOUR_USERNAME/hadooptmp|${HADOOP_TMP_DIR}|g" "${CONF_DIR}/core-site.xml" 2>/dev/null
        
        sed -i.bak "s|file:///home/YOUR_USERNAME/hadoopdata|file://${HADOOP_DATA_DIR}|g" "${CONF_DIR}/hdfs-site.xml" 2>/dev/null || \
        sed -i "" "s|file:///home/YOUR_USERNAME/hadoopdata|file://${HADOOP_DATA_DIR}|g" "${CONF_DIR}/hdfs-site.xml" 2>/dev/null
        
        rm -f "${CONF_DIR}/core-site.xml.bak" "${CONF_DIR}/hdfs-site.xml.bak"
    else
        echo -e "        ${YELLOW}[!] Generating fallback configurations...${NC}"
        cat << EOF > "${CONF_DIR}/core-site.xml"
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>${HADOOP_TMP_DIR}</value>
    </property>
</configuration>
EOF

        cat << EOF > "${CONF_DIR}/hdfs-site.xml"
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file://${HADOOP_DATA_DIR}/namenode</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file://${HADOOP_DATA_DIR}/datanode</value>
    </property>
</configuration>
EOF
        echo "localhost" > "${CONF_DIR}/workers"
    fi

    # Configure hadoop-env.sh
    sed -i.bak "s|^# export JAVA_HOME=.*|export JAVA_HOME=${detected_java_home}|g" "${CONF_DIR}/hadoop-env.sh" 2>/dev/null || \
    sed -i "" "s|^# export JAVA_HOME=.*|export JAVA_HOME=${detected_java_home}|g" "${CONF_DIR}/hadoop-env.sh" 2>/dev/null

    # Format NameNode
    echo -e "\n  ${GRAY}[8/8]${NC} Formatting HDFS NameNode system..."
    "${HADOOP_DEST}/bin/hdfs" namenode -format -force

    load_env

    echo -e "\n  ${GREEN}[✓] Installation of Hadoop ${selected_ver} completed successfully!${NC}"
    echo -e "      Reload your shell profile: ${YELLOW}source ${SHELL_CONFIG}${NC}"
    send_notification "Hadoop Handler" "Hadoop ${selected_ver} installation completed."
}

# In-Place Upgrade / Downgrade (Preserves HDFS Data Blocks)
upgrade_hadoop() {
    clear
    load_env
    echo -e "$DIVIDER"
    echo -e "  ${BCYAN}ACTION: In-Place Hadoop Upgrade / Downgrade${NC}"
    echo -e "$DIVIDER\n"

    if [ -z "$HADOOP_HOME" ] || [ ! -d "$HADOOP_HOME" ]; then
        echo -e "  ${RED}[!] Error: No active Hadoop installation found. Please run Install first.${NC}"
        return 1
    fi

    local current_ver=$(hadoop version 2>/dev/null | head -n 1 | awk '{print $2}')
    [ -z "$current_ver" ] && current_ver="3.4.2"
    echo -e "  Current Hadoop Version: ${CYAN}${current_ver}${NC}"

    local target_ver="$1"
    if [ -z "$target_ver" ]; then
        echo -e "\n  Select Target Hadoop Version to Migrate To:"
        echo -e "    1. 3.4.2 (Latest Stable, Java 8/11/17/21)"
        echo -e "    2. 3.4.1 (Java 8/11/17/21)"
        echo -e "    3. 3.3.6 (LTS Production, Java 8/11/17)"
        echo -e "    4. 3.3.5 (Java 8/11)"
        echo -e "    5. 3.2.4 (Legacy, Java 8/11)"
        echo -e "    6. Custom version"
        echo -e "    7. Cancel"
        read -p "  Enter choice [1-7]: " ver_choice
        case "$ver_choice" in
            1) target_ver="3.4.2" ;;
            2) target_ver="3.4.1" ;;
            3) target_ver="3.3.6" ;;
            4) target_ver="3.3.5" ;;
            5) target_ver="3.2.4" ;;
            6) read -p "  Enter target version (e.g. 3.4.0): " target_ver ;;
            *) echo -e "  Migration cancelled."; return 0 ;;
        esac
    fi

    if [ "$current_ver" = "$target_ver" ]; then
        echo -e "  ${YELLOW}[*] Cluster is already running Hadoop ${target_ver}.${NC}"
        return 0
    fi

    echo -e "\n  Target Hadoop Version: ${GREEN}${target_ver}${NC}"

    # Verify Java compatibility
    check_compatibility "$target_ver" "" || {
        echo -e "\n  ${YELLOW}[!] Warning: Current Java runtime may not be compatible with Hadoop ${target_ver}.${NC}"
        read -p "  Do you want to proceed anyway? (y/N): " ignore_compat
        if [[ ! "$ignore_compat" =~ ^[Yy]$ ]]; then
            echo -e "  Migration aborted. Please run 'hadoop-handler java switch' first."
            return 1
        fi
    }

    echo -e "\n  ${GRAY}[1/5]${NC} Stopping active cluster daemons..."
    stop_services >/dev/null 2>&1 || true

    echo -e "  ${GRAY}[2/5]${NC} Backing up cluster XML configurations..."
    local backup_dir="/tmp/hadoop_conf_backup_$(date +%s)"
    mkdir -p "$backup_dir"
    local conf_src="${HADOOP_HOME}/etc/hadoop"
    for f in core-site.xml hdfs-site.xml mapred-site.xml yarn-site.xml workers; do
        [ -f "${conf_src}/$f" ] && cp "${conf_src}/$f" "$backup_dir/"
    done
    echo -e "        Configuration backup saved to ${backup_dir}."

    local target_tar="hadoop-${target_ver}.tar.gz"
    local download_url=$(resolve_hadoop_url "$target_ver")
    echo -e "\n  ${GRAY}[3/5]${NC} Retrieving Hadoop ${target_ver}..."
    if [ ! -f "$HOME/Downloads/${target_tar}" ]; then
        download_file "$download_url" "$HOME/Downloads/${target_tar}" "Downloading Hadoop ${target_ver}" || {
            echo -e "  ${RED}[!] Download failed for ${target_ver}.${NC}"
            return 1
        }
    else
        echo -e "        Using cached archive: ~/Downloads/${target_tar}"
    fi

    echo -e "\n  ${GRAY}[4/5]${NC} Relocating binaries (preserving HDFS blocks)..."
    local hadoop_dest="${HADOOP_HOME}"
    if [ "$OS_NAME" = "Linux" ]; then
        sudo rm -rf "${hadoop_dest}"
        sudo tar -xzf "$HOME/Downloads/${target_tar}" -C /opt || { echo -e "  ${RED}[!] Extraction failed.${NC}"; return 1; }
        sudo mv "/opt/hadoop-${target_ver}" "${hadoop_dest}"
        sudo chown -R $USER:$USER "${hadoop_dest}"
    else
        rm -rf "${hadoop_dest}"
        tar -xzf "$HOME/Downloads/${target_tar}" -C "$HOME/" || { echo -e "  ${RED}[!] Extraction failed.${NC}"; return 1; }
        mv "$HOME/hadoop-${target_ver}" "${hadoop_dest}"
    fi

    echo -e "\n  ${GRAY}[5/5]${NC} Restoring cluster XML configurations..."
    local new_conf="${hadoop_dest}/etc/hadoop"
    cp "$backup_dir"/* "$new_conf/" 2>/dev/null || true
    
    if [ -n "$JAVA_HOME" ]; then
        sed -i.bak "s|^# export JAVA_HOME=.*|export JAVA_HOME=${JAVA_HOME}|g" "${new_conf}/hadoop-env.sh" 2>/dev/null || \
        sed -i '' "s|^# export JAVA_HOME=.*|export JAVA_HOME=${JAVA_HOME}|g" "${new_conf}/hadoop-env.sh" 2>/dev/null
    fi

    rm -rf "$backup_dir"

    echo -e "\n  ${GREEN}[✓] In-place migration to Hadoop ${target_ver} successful!${NC}"
    echo -e "      (Existing HDFS data blocks and cluster settings were preserved)."
    send_notification "Hadoop Handler" "Hadoop migrated to version ${target_ver}."

    read -p "  Do you want to start cluster services now? (Y/n): " start_now
    if [[ ! "$start_now" =~ ^[Nn]$ ]]; then
        start_services
    fi
}

# 2. Verify Hadoop Installation
verify_hadoop() {
    clear
    load_env
    echo -e "$DIVIDER"
    echo -e "  ${BCYAN}ACTION: Verifying Hadoop System Status${NC}"
    echo -e "$DIVIDER\n"
    
    if [ -z "$HADOOP_HOME" ] || [ ! -d "$HADOOP_HOME" ]; then
        echo -e "  ${RED}[!] Error: Hadoop is not installed or HADOOP_HOME is not set correctly.${NC}"
        return
    fi
    echo -e "  ${GRAY}HADOOP_HOME:${NC} ${GREEN}${HADOOP_HOME}${NC}"
    
    echo -ne "  ${GRAY}Hadoop binary:${NC} "
    if command -v hadoop >/dev/null 2>&1; then
        echo -e "${GREEN}Available${NC} ($(hadoop version | head -n 1))"
    else
        echo -e "${RED}Not found in PATH${NC} (Try sourcing shell profile)"
    fi

    echo -ne "  ${GRAY}Java version:${NC}  "
    if [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ]; then
        echo -e "${GREEN}Available${NC} ($("$JAVA_HOME/bin/java" -version 2>&1 | head -n 1))"
    elif command -v java >/dev/null 2>&1; then
        echo -e "${GREEN}Available${NC} ($(java -version 2>&1 | head -n 1))"
    else
        echo -e "${RED}Not found${NC}"
    fi

    echo -e "\n  ${GRAY}Active Cluster Daemons (jps):${NC}"
    echo -e "  $DIVIDER"
    if command -v jps >/dev/null 2>&1; then
        jps | sed 's/^/  /'
    else
        echo -e "  ${RED}'jps' command is not available. Please ensure OpenJDK is fully configured.${NC}"
    fi

    echo ""
    check_compatibility "" ""
}

# 3. Start Hadoop Services
start_services() {
    clear
    load_env
    echo -e "$DIVIDER"
    echo -e "  ${BCYAN}ACTION: Starting Hadoop Services (HDFS & YARN)${NC}"
    echo -e "$DIVIDER\n"
    
    if [ -z "$HADOOP_HOME" ] || [ ! -d "$HADOOP_HOME" ]; then
        echo -e "  ${RED}[!] Error: Hadoop is not installed. Please run Option 1 first.${NC}"
        return
    fi

    # Compatibility pre-flight check
    check_compatibility "" ""

    # Start HDFS (NameNode, DataNode, SecondaryNameNode)
    echo -e "\n  ${GRAY}[1/2]${NC} Starting Distributed File System (HDFS)..."
    if command -v start-dfs.sh >/dev/null 2>&1; then
        start-dfs.sh
    else
        "${HADOOP_HOME}/sbin/start-dfs.sh"
    fi

    # Start YARN (ResourceManager, NodeManager)
    echo -e "\n  ${GRAY}[2/2]${NC} Starting YARN Resource Negotiator..."
    if command -v start-yarn.sh >/dev/null 2>&1; then
        start-yarn.sh
    else
        "${HADOOP_HOME}/sbin/start-yarn.sh"
    fi

    echo -e "\n  ${GREEN}[✓] Active Hadoop daemons after startup:${NC}"
    echo -e "  $DIVIDER"
    if command -v jps >/dev/null 2>&1; then
        jps | sed 's/^/  /'
    fi
    send_notification "Hadoop Handler" "Hadoop cluster services (HDFS & YARN) started."
}

# 4. Stop Hadoop Services
stop_services() {
    clear
    load_env
    echo -e "$DIVIDER"
    echo -e "  ${BCYAN}ACTION: Stopping Hadoop Services (YARN & HDFS)${NC}"
    echo -e "$DIVIDER\n"
    
    if [ -z "$HADOOP_HOME" ] || [ ! -d "$HADOOP_HOME" ]; then
        echo -e "  ${RED}[!] Error: Hadoop is not installed.${NC}"
        return
    fi

    # Stop YARN
    echo -e "  ${GRAY}[1/2]${NC} Stopping YARN Resource Manager & Nodes..."
    if command -v stop-yarn.sh >/dev/null 2>&1; then
        stop-yarn.sh
    else
        "${HADOOP_HOME}/sbin/stop-yarn.sh"
    fi

    # Stop HDFS
    echo -e "\n  ${GRAY}[2/2]${NC} Stopping Distributed File System (HDFS)..."
    if command -v stop-dfs.sh >/dev/null 2>&1; then
        stop-dfs.sh
    else
        "${HADOOP_HOME}/sbin/stop-dfs.sh"
    fi

    echo -e "\n  ${GREEN}[✓] Remaining active daemons:${NC}"
    echo -e "  $DIVIDER"
    if command -v jps >/dev/null 2>&1; then
        jps | sed 's/^/  /'
    fi
    send_notification "Hadoop Handler" "Hadoop cluster services stopped."
}

# 5. Delete Hadoop Completely
delete_hadoop() {
    clear
    echo -e "$DIVIDER"
    echo -e "  ${BRED}ACTION: Completely Uninstalling Hadoop${NC}"
    echo -e "$DIVIDER\n"
    
    echo -e "  ${RED}[!] WARNING: This will permanently delete your Hadoop installation,${NC}"
    echo -e "  ${RED}    configuration files, HDFS directories, and path profiles.${NC}\n"
    read -p "  Are you sure you want to proceed? (y/N): " confirm
    
    if [[ "$confirm" =~ ^[Yy]$ ]]; then
        load_env
        
        stop_services >/dev/null 2>&1 || true
        
        echo -e "\n  ${GRAY}[1/3]${NC} Deleting binaries and directories..."
        if [ -d "$HADOOP_HOME" ]; then
            if [ "$OS_NAME" = "Linux" ]; then
                sudo rm -rf "$HADOOP_HOME" /opt/hadoop_data /opt/hadoop_tmp
            else
                rm -rf "$HADOOP_HOME" ~/hadoopdata ~/hadooptmp /Users/Shared/hadoop /Users/Shared/hadoop_data /Users/Shared/hadoop_tmp
            fi
            echo -e "        Deleted ${HADOOP_HOME} and data directories."
        fi

        echo -e "\n  ${GRAY}[2/3]${NC} Removing downloaded archives..."
        rm -f "$HOME"/Downloads/hadoop-*.tar.gz
        echo -e "        Removed tarball cache."

        echo -e "\n  ${GRAY}[3/3]${NC} Cleaning up environment variables..."
        for profile in "$HOME/.bashrc" "$HOME/.zshrc"; do
            if [ -f "$profile" ]; then
                sed -i.bak '/# --- HADOOP HANDLER ENVIRONMENT VARIABLES ---/,/export PATH=.*HADOOP/d' "$profile" 2>/dev/null || \
                sed -i '' '/# --- HADOOP HANDLER ENVIRONMENT VARIABLES ---/,/export PATH=.*HADOOP/d' "$profile" 2>/dev/null
                rm -f "${profile}.bak"
                echo -e "        Cleaned environment variables from ${profile}."
            fi
        done

        unset HADOOP_HOME HADOOP_CONF_DIR HADOOP_COMMON_HOME HADOOP_HDFS_HOME HADOOP_MAPRED_HOME YARN_HOME HADOOP_COMMON_LIB_NATIVE_DIR

        echo -e "\n  ${GREEN}[✓] Uninstall completed. Please reload your shell profile:${NC}"
        echo -e "      ${YELLOW}source ~/.bashrc${NC} (or ${YELLOW}source ~/.zshrc${NC})"
        send_notification "Hadoop Handler" "Hadoop installation uninstalled."
    else
        echo -e "  ${YELLOW}Uninstall aborted.${NC}"
    fi
}

# 6. System Service Integration (systemd / launchd)
manage_system_service() {
    local action="$1"
    
    if [ "$OS_NAME" = "Linux" ]; then
        local unit_dir="$HOME/.config/systemd/user"
        local unit_file="${unit_dir}/hadoop.service"
        local hadoop_bin="$(command -v hadoop-handler 2>/dev/null || echo "${SCRIPT_DIR}/hadoop-handler")"
        
        if [ -z "$action" ]; then
            clear
            echo -e "$DIVIDER"
            echo -e "  ${BCYAN}ACTION: System Service Integration (systemd)${NC}"
            echo -e "$DIVIDER"
            echo -e "  1. Enable Hadoop service on boot/login (systemd user unit)"
            echo -e "  2. Disable Hadoop service"
            echo -e "  3. View service status (systemctl --user status hadoop)"
            echo -e "  4. Start service via systemctl"
            echo -e "  5. Stop service via systemctl"
            echo -e "  6. Back to main menu"
            echo -e "$DIVIDER"
            read -p "  Select action [1-6]: " svc_choice
            case "$svc_choice" in
                1) action="enable" ;;
                2) action="disable" ;;
                3) action="status" ;;
                4) action="start" ;;
                5) action="stop" ;;
                *) return 0 ;;
            esac
        fi
        
        case "$action" in
            enable)
                echo -e "  [+] Generating user systemd unit: ${unit_file}..."
                mkdir -p "$unit_dir"
                cat << EOF > "$unit_file"
[Unit]
Description=Apache Hadoop Single-Node Services (HDFS & YARN)
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
Environment="HADOOP_HOME=${HADOOP_HOME:-/opt/hadoop}"
Environment="JAVA_HOME=${JAVA_HOME}"
ExecStart=${hadoop_bin} start
ExecStop=${hadoop_bin} stop

[Install]
WantedBy=default.target
EOF
                systemctl --user daemon-reload
                systemctl --user enable hadoop.service
                echo -e "  ${GREEN}[✓] Hadoop service enabled!${NC}"
                echo -e "      Hadoop services will now automatically launch on user login."
                send_notification "Hadoop Handler" "Hadoop systemd user service enabled."
                ;;
            disable)
                echo -e "  [+] Disabling Hadoop systemd service..."
                systemctl --user stop hadoop.service 2>/dev/null || true
                systemctl --user disable hadoop.service 2>/dev/null || true
                rm -f "$unit_file"
                systemctl --user daemon-reload
                echo -e "  ${GREEN}[✓] Hadoop systemd service disabled and unit removed.${NC}"
                send_notification "Hadoop Handler" "Hadoop systemd service disabled."
                ;;
            status)
                systemctl --user status hadoop.service --no-pager
                ;;
            start)
                echo -e "  [+] Starting hadoop.service via systemctl..."
                systemctl --user start hadoop.service
                echo -e "  ${GREEN}[✓] Signal dispatched to systemd.${NC}"
                ;;
            stop)
                echo -e "  [+] Stopping hadoop.service via systemctl..."
                systemctl --user stop hadoop.service
                echo -e "  ${GREEN}[✓] Signal dispatched to systemd.${NC}"
                ;;
            *)
                echo -e "  ${RED}[!] Unknown service action: ${action}${NC}"
                ;;
        esac
    elif [ "$OS_NAME" = "Darwin" ]; then
        local plist_dir="$HOME/Library/LaunchAgents"
        local plist_file="${plist_dir}/in.adityapidurkar.hadoop.plist"
        local hadoop_bin="$(command -v hadoop-handler 2>/dev/null || echo "${SCRIPT_DIR}/hadoop-handler")"

        case "$action" in
            enable)
                mkdir -p "$plist_dir"
                cat << EOF > "$plist_file"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>in.adityapidurkar.hadoop</string>
    <key>ProgramArguments</key>
    <array>
        <string>${hadoop_bin}</string>
        <string>start</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF
                launchctl load "$plist_file" 2>/dev/null || true
                echo -e "  ${GREEN}[✓] LaunchAgent enabled for macOS.${NC}"
                send_notification "Hadoop Handler" "Hadoop LaunchAgent service enabled."
                ;;
            disable)
                launchctl unload "$plist_file" 2>/dev/null || true
                rm -f "$plist_file"
                echo -e "  ${GREEN}[✓] LaunchAgent disabled for macOS.${NC}"
                ;;
            *)
                echo -e "  ${YELLOW}Use 'enable' or 'disable' on macOS.${NC}"
                ;;
        esac
    fi
}

# 7. Check for Updates and Perform In-Place Self-Update
self_update() {
    clear
    echo -e "$DIVIDER"
    echo -e "  ${BCYAN}ACTION: Checking & Updating Hadoop Handler${NC}"
    echo -e "$DIVIDER\n"

    local updated=false

    if [ -d "$HOME/.hadoop-handler/.git" ]; then
        echo -e "  [+] Checking global installation in ~/.hadoop-handler..."
        (cd "$HOME/.hadoop-handler" && git pull origin main)
        chmod +x "$HOME/.hadoop-handler/hadoop-handler" "$HOME/.hadoop-handler/setup.sh" 2>/dev/null || true
        updated=true
    fi

    if [ -d "${SCRIPT_DIR}/.git" ] && [ "${SCRIPT_DIR}" != "$HOME/.hadoop-handler" ]; then
        echo -e "  [+] Pulling latest changes in ${SCRIPT_DIR}..."
        (cd "${SCRIPT_DIR}" && git pull origin main)
        chmod +x "${SCRIPT_DIR}/hadoop-handler" 2>/dev/null || true
        updated=true
    fi

    if command -v pip >/dev/null 2>&1 && pip list 2>/dev/null | grep -q "hadoop-handler"; then
        echo -e "  [+] Upgrading pip package..."
        pip install --upgrade hadoop-handler 2>/dev/null || true
        updated=true
    elif command -v python3 >/dev/null 2>&1 && python3 -m pip list 2>/dev/null | grep -q "hadoop-handler"; then
        echo -e "  [+] Upgrading python3 pip package..."
        python3 -m pip install --upgrade hadoop-handler 2>/dev/null || true
        updated=true
    fi

    rm -f "$HOME/.hadoop-handler/.version_cache" 2>/dev/null || true

    if [ "$updated" = "true" ]; then
        echo -e "\n  ${GREEN}[✓] Hadoop Handler is up to date!${NC}"
        send_notification "Hadoop Handler" "Hadoop Handler updated to the latest version."
    else
        echo -e "\n  ${YELLOW}[*] No git or pip package found to update.${NC}"
    fi
}

# 8. Shell Autocompletion
install_shell_completion() {
    local target_shell="$1"
    if [ -z "$target_shell" ]; then
        target_shell="$(basename "$SHELL")"
    fi

    clear
    echo -e "$DIVIDER"
    echo -e "  ${BCYAN}ACTION: Installing Shell Autocompletion (${target_shell})${NC}"
    echo -e "$DIVIDER\n"

    case "$target_shell" in
        bash)
            local rc_file="$HOME/.bashrc"
            if ! grep -q "_hadoop_handler_completions" "$rc_file" 2>/dev/null; then
                cat << "EOF" >> "$rc_file"

# Hadoop Handler shell completion
_hadoop_handler_completions() {
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="diagnose install verify status start stop restart upgrade check-compat java delete service update completion --version --help --install-completion"

    if [ "$prev" = "service" ]; then
        COMPREPLY=( $(compgen -W "enable disable status start stop" -- "$cur") )
        return 0
    elif [ "$prev" = "java" ]; then
        COMPREPLY=( $(compgen -W "list switch use" -- "$cur") )
        return 0
    elif [ "$prev" = "completion" ]; then
        COMPREPLY=( $(compgen -W "bash zsh fish powershell" -- "$cur") )
        return 0
    fi

    COMPREPLY=( $(compgen -W "${opts}" -- "$cur") )
    return 0
}
complete -F _hadoop_handler_completions hadoop-handler
EOF
                echo -e "  ${GREEN}[✓] Bash completions added to ${rc_file}!${NC}"
                echo -e "      To activate immediately, run: ${YELLOW}source ${rc_file}${NC}"
            else
                echo -e "  ${YELLOW}[*] Completions already registered in ${rc_file}.${NC}"
            fi
            ;;
        zsh)
            local rc_file="$HOME/.zshrc"
            if ! grep -q "_hadoop_handler_completions" "$rc_file" 2>/dev/null; then
                cat << "EOF" >> "$rc_file"

# Hadoop Handler shell completion
autoload -Uz bashcompinit && bashcompinit
_hadoop_handler_completions() {
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="diagnose install verify status start stop restart upgrade check-compat java delete service update completion --version --help --install-completion"

    if [ "$prev" = "service" ]; then
        COMPREPLY=( $(compgen -W "enable disable status start stop" -- "$cur") )
        return 0
    elif [ "$prev" = "java" ]; then
        COMPREPLY=( $(compgen -W "list switch use" -- "$cur") )
        return 0
    elif [ "$prev" = "completion" ]; then
        COMPREPLY=( $(compgen -W "bash zsh fish powershell" -- "$cur") )
        return 0
    fi

    COMPREPLY=( $(compgen -W "${opts}" -- "$cur") )
    return 0
}
complete -F _hadoop_handler_completions hadoop-handler
EOF
                echo -e "  ${GREEN}[✓] Zsh completions added to ${rc_file}!${NC}"
                echo -e "      To activate immediately, run: ${YELLOW}source ${rc_file}${NC}"
            else
                echo -e "  ${YELLOW}[*] Completions already registered in ${rc_file}.${NC}"
            fi
            ;;
        fish)
            local fish_dir="$HOME/.config/fish/completions"
            mkdir -p "$fish_dir"
            cat << "EOF" > "${fish_dir}/hadoop-handler.fish"
complete -c hadoop-handler -f -a "diagnose install verify status start stop restart upgrade check-compat java delete service update completion --version --help --install-completion"
complete -c hadoop-handler -n "__fish_seen_subcommand_from service" -f -a "enable disable status start stop"
complete -c hadoop-handler -n "__fish_seen_subcommand_from java" -f -a "list switch use"
complete -c hadoop-handler -n "__fish_seen_subcommand_from completion" -f -a "bash zsh fish powershell"
EOF
            echo -e "  ${GREEN}[✓] Fish completions saved to ${fish_dir}/hadoop-handler.fish!${NC}"
            ;;
        powershell)
            cat << "EOF"
Register-ArgumentCompleter -Native -CommandName hadoop-handler -ScriptBlock {
    param($wordToComplete, $commandAst, $cursorPosition)
    $commands = @('diagnose', 'install', 'verify', 'status', 'start', 'stop', 'restart', 'upgrade', 'check-compat', 'java', 'delete', 'service', 'update', 'completion', '--version', '--help')
    $commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
    }
}
EOF
            echo -e "  ${GREEN}[✓] Add the snippet above to your PowerShell profile (\$PROFILE).${NC}"
            ;;
        *)
            echo -e "  ${RED}[!] Unsupported shell: ${target_shell}.${NC}"
            ;;
    esac
}

# 0. Diagnose Environment
diagnose_environment() {
    clear
    echo -e "$DIVIDER"
    echo -e "  ${BCYAN}ACTION: Diagnosing System Dependencies${NC}"
    echo -e "$DIVIDER\n"
    
    local missing_deps=()
    local repair_cmds=()
    
    echo -e "  ${GRAY}Scanning critical utilities...${NC}"
    
    local pkg_manager=""
    if [ "$OS_NAME" = "Linux" ]; then
        if command -v apt-get >/dev/null 2>&1; then
            pkg_manager="apt"
        elif command -v dnf >/dev/null 2>&1; then
            pkg_manager="dnf"
        elif command -v yum >/dev/null 2>&1; then
            pkg_manager="yum"
        elif command -v pacman >/dev/null 2>&1; then
            pkg_manager="pacman"
        elif command -v zypper >/dev/null 2>&1; then
            pkg_manager="zypper"
        fi
    elif [ "$OS_NAME" = "Darwin" ]; then
        if command -v brew >/dev/null 2>&1; then
            pkg_manager="brew"
        fi
    fi

    check_dependency() {
        local cmd=$1
        local pkg_apt=$2
        local pkg_dnf=$3
        local pkg_pacman=$4
        local pkg_brew=$5

        echo -ne "  - Checking for ${CYAN}${cmd}${NC}... "
        if command -v "$cmd" >/dev/null 2>&1; then
            echo -e "${GREEN}[OK]${NC}"
        else
            echo -e "${RED}[MISSING]${NC}"
            missing_deps+=("$cmd")
            case "$pkg_manager" in
                apt) [ -n "$pkg_apt" ] && repair_cmds+=("sudo apt-get install -y $pkg_apt") ;;
                dnf|yum) [ -n "$pkg_dnf" ] && repair_cmds+=("sudo $pkg_manager install -y $pkg_dnf") ;;
                pacman) [ -n "$pkg_pacman" ] && repair_cmds+=("sudo pacman -S --noconfirm $pkg_pacman") ;;
                brew) [ -n "$pkg_brew" ] && repair_cmds+=("brew install $pkg_brew") ;;
            esac
        fi
    }

    check_dependency "curl" "curl" "curl" "curl" "curl"
    check_dependency "tar" "tar" "tar" "tar" ""
    check_dependency "ssh" "openssh-client openssh-server" "openssh-clients openssh-server" "openssh" ""
    check_dependency "rsync" "rsync" "rsync" "rsync" "rsync"
    
    echo -ne "  - Checking for ${CYAN}Java Runtime (OpenJDK)${NC}... "
    if command -v java >/dev/null 2>&1; then
        local jv=$(java -version 2>&1 | head -n 1 | awk -F '"' '{print $2}')
        echo -e "${GREEN}[OK] (${jv})${NC}"
    else
        echo -e "${RED}[MISSING]${NC}"
        missing_deps+=("java")
        case "$pkg_manager" in
            apt) repair_cmds+=("sudo apt-get install -y openjdk-21-jdk") ;;
            dnf|yum) repair_cmds+=("sudo $pkg_manager install -y java-21-openjdk-devel") ;;
            pacman) repair_cmds+=("sudo pacman -S --noconfirm jre21-openjdk jdk21-openjdk") ;;
            brew) repair_cmds+=("brew install openjdk@21") ;;
        esac
    fi

    if [ "$OS_NAME" = "Linux" ]; then
        echo -ne "  - Checking for ${CYAN}SSH Daemon (sshd)${NC}... "
        if systemctl is-active --quiet ssh 2>/dev/null || systemctl is-active --quiet sshd 2>/dev/null; then
            echo -e "${GREEN}[RUNNING]${NC}"
        else
            echo -e "${YELLOW}[NOT RUNNING]${NC}"
            missing_deps+=("sshd_service")
            repair_cmds+=("sudo systemctl enable --now ssh 2>/dev/null || sudo systemctl enable --now sshd")
        fi
    fi

    echo -e "\n$DIVIDER"
    if [ ${#missing_deps[@]} -eq 0 ]; then
        echo -e "  ${GREEN}[✓] System scan complete! All dependencies are satisfied.${NC}"
        rm -f /tmp/hadoop_repair_cmds.txt /tmp/hadoop_repair_missing.txt
        return 0
    else
        echo -e "  ${YELLOW}[!] Diagnostics identified ${#missing_deps[@]} missing requirement(s).${NC}"
        printf "%s\n" "${repair_cmds[@]}" > /tmp/hadoop_repair_cmds.txt
        printf "%s\n" "${missing_deps[@]}" > /tmp/hadoop_repair_missing.txt
        return 1
    fi
}

apply_repairs() {
    local dry_run=$1
    if [ ! -f /tmp/hadoop_repair_cmds.txt ]; then
        echo -e "  ${YELLOW}No pending repairs found. Please run Diagnostics first.${NC}"
        return 0
    fi
    
    if [ "$dry_run" = "true" ]; then
        echo -e "\n  ${BCYAN}--- DRY RUN MODE ---${NC}"
        echo -e "  The following commands would be executed:"
        while read -r cmd; do
            echo -e "  > $cmd"
        done < /tmp/hadoop_repair_cmds.txt
        return 0
    fi

    echo -e "\n  ${BCYAN}ACTION: Applying Repairs${NC}"
    echo -e "  $DIVIDER"
    
    while read -r cmd; do
        echo -e "  ${GRAY}Executing: $cmd${NC}"
        eval "$cmd"
        if [ $? -ne 0 ]; then
            echo -e "  ${RED}[!] Repair step failed: $cmd${NC}"
            echo -e "  ${YELLOW}Aborting further repairs.${NC}"
            rm -f /tmp/hadoop_repair_cmds.txt /tmp/hadoop_repair_missing.txt
            return 1
        fi
    done < /tmp/hadoop_repair_cmds.txt
    
    echo -e "  ${GREEN}[✓] All repairs completed successfully!${NC}"
    rm -f /tmp/hadoop_repair_cmds.txt /tmp/hadoop_repair_missing.txt
    send_notification "Hadoop Handler" "System dependency repairs finished."
}

diagnose_and_repair() {
    diagnose_environment
    if [ -f /tmp/hadoop_repair_cmds.txt ]; then
        echo -e "\n  Do you want to apply these repairs now? (y/N/dryrun)"
        read -p "  > " confirm
        if [[ "$confirm" =~ ^[Yy]$ ]]; then
            apply_repairs "false"
        elif [[ "$confirm" == "dryrun" ]]; then
            apply_repairs "true"
        else
            echo -e "  ${YELLOW}Repairs cancelled.${NC}"
        fi
    fi
}

# ==============================================================================
#  TUI RENDERER & INTERACTIVE NAVIGATION
# ==============================================================================

show_banner_and_status() {
    echo -e "${CYAN}"
    cat << "EOF"
█ █  ███  ██   ███  ███  ███    █ █  ███  ██ █  ██   █    ███  ███
███  █ █  █ █  █ █  █ █  ███    ███  █ █  █ ██  █ █  █    ██   ███
█ █  █ █  ██   ███  ███  █      █ █  █ █  █  █  ██   ███  ███  █ █
EOF
    echo -e "${NC}"
    echo -e "  ${GRAY}Developer:${NC} ${BCYAN}Aditya Pidurkar${NC} (${CYAN}github.com/itsadityapidurkar${NC})"
    echo -e "  ${GRAY}Scope:${NC}     Apache Hadoop Single-Node Control Center (v${CURRENT_VERSION})"
    echo -e "$DIVIDER"
    
    check_version_banner

    local h_stat=""
    if command -v hadoop >/dev/null 2>&1; then
        local h_ver=$(hadoop version 2>/dev/null | head -n 1 | awk '{print $2}')
        [ -z "$h_ver" ] && h_ver="Installed"
        h_stat="${BGREEN}[✓ Installed (${h_ver})]${NC}"
    elif [ -n "$HADOOP_HOME" ] && [ -d "$HADOOP_HOME" ]; then
        h_stat="${BGREEN}[✓ Installed]${NC}"
    else
        h_stat="${BRED}[✗ Not Installed]${NC}"
    fi

    local j_stat=""
    if [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ]; then
        local j_ver=$("$JAVA_HOME/bin/java" -version 2>&1 | head -n 1 | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f1)
        [ "$j_ver" = "1" ] && j_ver=$("$JAVA_HOME/bin/java" -version 2>&1 | head -n 1 | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f2)
        j_stat="${BGREEN}[✓ Java ${j_ver}]${NC}"
    elif command -v java >/dev/null 2>&1; then
        local j_ver=$(java -version 2>&1 | head -n 1 | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f1)
        [ "$j_ver" = "1" ] && j_ver=$(java -version 2>&1 | head -n 1 | sed -E 's/.*version "([^"]+)".*/\1/' | cut -d'.' -f2)
        j_stat="${BGREEN}[✓ Java ${j_ver}]${NC}"
    else
        j_stat="${BRED}[✗ Missing]${NC}"
    fi

    local s_stat=""
    local d_count=0
    if command -v jps >/dev/null 2>&1; then
        for d in NameNode DataNode SecondaryNameNode ResourceManager NodeManager; do
            if jps 2>/dev/null | grep -wq "$d"; then
                ((d_count++))
            fi
        done
    fi

    if [ $d_count -eq 5 ]; then
        s_stat="${BGREEN}[✓ 5/5 Daemons Running]${NC}"
    elif [ $d_count -gt 0 ]; then
        s_stat="${YELLOW}[● ${d_count}/5 Daemons Running]${NC}"
    else
        s_stat="${GRAY}[● Stopped]${NC}"
    fi

    echo -e "  ${GRAY}Cluster Status:${NC}"
    echo -e "    Hadoop:   ${h_stat}"
    echo -e "    Java:     ${j_stat}"
    echo -e "    Services: ${s_stat}"
}

MENU_OPTIONS=(
    "Diagnose/Repair System Dependencies"
    "Install Hadoop (Dynamic Version Selector)"
    "Verify Hadoop Installation & Daemons"
    "Hadoop <-> Java Compatibility Checker"
    "Start Hadoop Services (HDFS & YARN)"
    "Stop Hadoop Services"
    "Restart Hadoop Services"
    "Java Runtime Selector & Switcher"
    "In-Place Hadoop Upgrade / Downgrade"
    "Delete Hadoop Completely"
    "System Service Integration (systemd)"
    "Check for Updates (Self-Update)"
    "Install Shell Autocompletion"
    "Exit"
)

MENU_CHOICE=""

render_options() {
    local selected="$1"
    local num_options=${#MENU_OPTIONS[@]}
    for i in "${!MENU_OPTIONS[@]}"; do
        if [ "$i" -eq "$selected" ]; then
            printf "\033[2K  %b▶%b %b[ %2d ] %s%b\n" "$BCYAN" "$NC" "$BGREEN" "$i" "${MENU_OPTIONS[$i]}" "$NC"
        else
            printf "\033[2K    %b[ %2d ]%b %s\n" "$GRAY" "$i" "$NC" "${MENU_OPTIONS[$i]}"
        fi
    done
    printf "\033[2K%b\n" "$DIVIDER"
    printf "\033[2K  %bUse [↑/↓] (or j/k) and [Enter] to select, or press [0-%d] directly%b\n" "$GRAY" "$((num_options - 1))" "$NC"
}

# Arrow-Key Navigation Menu Selector (Zero Flicker)
select_menu_option() {
    MENU_CHOICE=""
    local selected=0
    local key=""
    local num_options=${#MENU_OPTIONS[@]}
    local lines_count=$((num_options + 2))

    if [ ! -t 0 ]; then
        clear
        show_banner_and_status
        echo -e "$DIVIDER"
        for i in "${!MENU_OPTIONS[@]}"; do
            echo -e "  [ $i ] ${MENU_OPTIONS[$i]}"
        done
        echo -e "$DIVIDER"
        read -r choice || choice=13
        MENU_CHOICE="${choice:-13}"
        return 0
    fi

    clear
    show_banner_and_status
    echo -e "$DIVIDER"

    tput civis 2>/dev/null || printf "\033[?25l"
    trap 'tput cnorm 2>/dev/null || printf "\033[?25h"' RETURN EXIT INT TERM

    render_options "$selected"

    while true; do
        IFS= read -rsn1 key
        local old_selected=$selected

        if [ "$key" = $'\x1b' ]; then
            read -rsn2 -t 0.1 rest
            key+="$rest"
            case "$key" in
                $'\x1b[A'|$'\x1bOA')
                    ((selected--))
                    [ $selected -lt 0 ] && selected=$((num_options - 1))
                    ;;
                $'\x1b[B'|$'\x1bOB')
                    ((selected++))
                    [ $selected -ge $num_options ] && selected=0
                    ;;
            esac
        elif [ "$key" = "k" ] || [ "$key" = "K" ]; then
            ((selected--))
            [ $selected -lt 0 ] && selected=$((num_options - 1))
        elif [ "$key" = "j" ] || [ "$key" = "J" ]; then
            ((selected++))
            [ $selected -ge $num_options ] && selected=0
        elif [ -z "$key" ] || [ "$key" = $'\n' ]; then
            break
        elif [[ "$key" =~ ^[0-9]$ ]] && [ "$key" -lt "$num_options" ]; then
            selected="$key"
            break
        elif [ "$key" = "q" ] || [ "$key" = "Q" ]; then
            selected=$((num_options - 1))
            break
        fi

        if [ "$selected" -ne "$old_selected" ]; then
            printf "\033[%dA" "$lines_count"
            render_options "$selected"
        fi
    done

    tput cnorm 2>/dev/null || printf "\033[?25h"
    MENU_CHOICE="$selected"
}

# ==============================================================================
#  CLI DISPATCHER & MAIN LOOP
# ==============================================================================

load_env

if [ -n "$1" ]; then
    case "$1" in
        0|diagnose|repair)
            diagnose_and_repair
            exit $?
            ;;
        1|install)
            shift
            install_hadoop "$@"
            exit $?
            ;;
        2|verify|status)
            verify_hadoop
            exit $?
            ;;
        check-compat|compat)
            shift
            clear
            echo -e "$DIVIDER"
            echo -e "  ${BCYAN}ACTION: Hadoop <-> Java Compatibility Checker${NC}"
            echo -e "$DIVIDER\n"
            check_compatibility "$1" "$2"
            exit $?
            ;;
        3|start)
            start_services
            exit $?
            ;;
        4|stop)
            stop_services
            exit $?
            ;;
        restart)
            stop_services
            sleep 2
            start_services
            exit $?
            ;;
        java)
            shift
            sub_cmd="$1"
            shift
            case "$sub_cmd" in
                list) manage_java "list" ;;
                use) manage_java "use" "$1" ;;
                switch|*) manage_java "switch" "$1" ;;
            esac
            exit $?
            ;;
        upgrade)
            shift
            upgrade_hadoop "$1"
            exit $?
            ;;
        5|delete)
            delete_hadoop
            exit $?
            ;;
        6|service)
            shift
            manage_system_service "$@"
            exit $?
            ;;
        7|update|self-update)
            self_update
            exit $?
            ;;
        8|completion)
            shift
            install_shell_completion "$@"
            exit $?
            ;;
        --install-completion)
            install_shell_completion
            exit $?
            ;;
        menu)
            # Fall through to menu loop
            ;;
        -v|--version)
            echo "hadoop-handler ${CURRENT_VERSION}"
            exit 0
            ;;
        -h|--help)
            echo "Hadoop Handler v${CURRENT_VERSION} — Single-Node Cluster Control Center"
            echo "Usage: hadoop-handler [command] [options]"
            echo ""
            echo "Commands:"
            echo "  (no args)                     Launch interactive TUI control panel"
            echo "  install [--version <ver>]     Install Hadoop with version selection"
            echo "  upgrade [<target_version>]    In-place upgrade/downgrade preserving HDFS data"
            echo "  check-compat [<h_ver>] [<j>]  Check Hadoop and Java matrix compatibility"
            echo "  java list                     List all detected Java runtimes"
            echo "  java use <path|version>       Switch active Java runtime for Hadoop"
            echo "  java switch                   Interactively switch active Java runtime"
            echo "  verify, status                Check Hadoop and Java status and running daemons"
            echo "  start                         Start Hadoop services (HDFS & YARN)"
            echo "  stop                          Stop Hadoop services"
            echo "  restart                       Restart all cluster daemons"
            echo "  delete                        Delete Hadoop cluster installation completely"
            echo "  service <action>              Manage system service (enable|disable|status|start|stop)"
            echo "  update                        Check and perform in-place self-update"
            echo "  completion <shell>            Generate autocompletion script"
            echo "  --install-completion          Automatically install autocompletion for current shell"
            echo "  -v, --version                 Show version"
            echo "  -h, --help                    Show this help message"
            exit 0
            ;;
        *)
            echo "Unknown command: $1"
            echo "Run 'hadoop-handler --help' for usage."
            exit 1
            ;;
    esac
fi

while true; do
    select_menu_option

    case $MENU_CHOICE in
        0)
            diagnose_and_repair
            pause_screen
            ;;
        1)
            install_hadoop
            pause_screen
            ;;
        2)
            verify_hadoop
            pause_screen
            ;;
        3)
            clear
            echo -e "$DIVIDER"
            echo -e "  ${BCYAN}ACTION: Hadoop <-> Java Compatibility Checker${NC}"
            echo -e "$DIVIDER\n"
            check_compatibility "" ""
            pause_screen
            ;;
        4)
            start_services
            pause_screen
            ;;
        5)
            stop_services
            pause_screen
            ;;
        6)
            stop_services
            sleep 2
            start_services
            pause_screen
            ;;
        7)
            manage_java "switch"
            pause_screen
            ;;
        8)
            upgrade_hadoop
            pause_screen
            ;;
        9)
            delete_hadoop
            pause_screen
            ;;
        10)
            manage_system_service
            pause_screen
            ;;
        11)
            self_update
            pause_screen
            ;;
        12)
            install_shell_completion
            pause_screen
            ;;
        13)
            clear
            echo -e "\n  Exiting Hadoop Handler. Goodbye!"
            exit 0
            ;;
        *)
            echo -e "  ${RED}[!] Invalid choice.${NC}"
            sleep 1.2
            ;;
    esac
done
