#!/bin/bash

# Define paths
ABS_DIR="/abs"
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$BASE_DIR/ABSApplications/config/custom_properties.cfg"
INF_CONFIG="$BASE_DIR/ABSApplications/config/infinity_properties.cfg"
VERSION_FILE="$BASE_DIR/ABSApplications/bin/update_version.ini"
BACKUP_BASE="$BASE_DIR/ABSApplications/Backup"
TMP_DIR="$ABS_DIR/tmp/abs_update_$$"

# Remote URLs
REMOTE_INI="https://download.abssolute.net/ABSSolute/Tools/ABSApplications/new_version.ini"
REMOTE_ZIP="https://download.abssolute.net/ABSSolute/Tools/ABSApplications/ABSApplications.zip"

# Colors
GREEN="\e[32m"
YELLOW="\e[93m"
BLUE="\e[94m"
RED="\e[31m"
RESET="\e[0m"

################################################################################
# Initial Setup if folder is missing
################################################################################
if [[ ! -d "$BASE_DIR/ABSApplications" ]]; then
    echo -e "${YELLOW}>>> ABSApplications directory not found. Starting initial setup...${RESET}"
    
    # Create necessary structure
    mkdir -p "$BASE_DIR/ABSApplications/"{bin,config,Backup,config/Compatibility}
    mkdir -p "$TMP_DIR"

    echo -e "${BLUE}>>> Downloading base package from $REMOTE_ZIP...${RESET}"
    if wget -q --show-progress -O "$TMP_DIR/initial_setup.zip" "$REMOTE_ZIP"; then
        echo -e "${BLUE}>>> Extracting files...${RESET}"
        unzip -oq "$TMP_DIR/initial_setup.zip" -d "$BASE_DIR/"
		echo -e "${BLUE}>>> Applying folder and script permissions...${RESET}"
        find "$BASE_DIR/ABSApplications" -type d -exec chmod 775 {} +
        find "$BASE_DIR/ABSApplications/bin" -name "*.sh" -exec chmod 755 {} +
        chmod 755 "$0"
        
        # Pull the version file immediately to avoid update loops
        wget -q --no-cache -O "$VERSION_FILE" "$REMOTE_INI"
        
        # Clean up
        rm -rf "$TMP_DIR"
        echo -e "${GREEN}>>> Initial setup complete.${RESET}"
        
        # Reload version variable since we just downloaded it
        SCRIPT_VERSION=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' "$VERSION_FILE" | head -1)
    else
        echo -e "${RED}>>> Error: Could not download initial package. Check internet connection.${RESET}"
        rm -rf "$TMP_DIR"
        exit 1
    fi
fi

# --- ADD THIS: Extract Version once ---
if [[ -f "$VERSION_FILE" ]]; then
    # Extracts the version number (e.g., 2.0.1) from the .ini file
    SCRIPT_VERSION=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' "$VERSION_FILE" | head -1)
else
    SCRIPT_VERSION="Unknown"
fi
################################################################################
# UPDATE MECHANISM
################################################################################
check_for_updates() {
    echo -e "${BLUE}>>> Checking for script updates and compatibility matrix...${RESET}"
    
    # Ensure TMP_DIR is clean
    rm -rf "$TMP_DIR"
    mkdir -p "$TMP_DIR/Compatibility"

    # 1. Download remote version info
    wget -q --no-cache -O "$TMP_DIR/new_version.ini" "$REMOTE_INI"
    
    if [[ ! -f "$TMP_DIR/new_version.ini" ]]; then
        echo -e "${YELLOW}Warning: Update server unreachable.${RESET}"
        return 0
    fi

    # 2. Extract versions
    LOCAL_VER=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' "$VERSION_FILE" | head -1 | xargs)
    REMOTE_VER=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' "$TMP_DIR/new_version.ini" | head -1 | xargs)

    # 3. Handle Compatibility Matrix (Always update these files)
    echo -e "${BLUE}>>> Refreshing Compatibility Matrix...${RESET}"
    COMPAT_URL="https://download.abssolute.net/ABSSolute/Tools/ABSApplications/Compatibility"
    COMPAT_LOCAL_DIR="$BASE_DIR/ABSApplications/config/Compatibility"
    mkdir -p "$COMPAT_LOCAL_DIR"

    for cfg in ABSMessageAgent.cfg APIGateway.cfg ABSMobileGateway.cfg Infinity.cfg; do
        wget -q --no-cache -O "$COMPAT_LOCAL_DIR/$cfg" "$COMPAT_URL/$cfg"
    done

    # 4. Check if Script update is needed
    if [[ "$LOCAL_VER" == "$REMOTE_VER" ]]; then
        echo -e "${GREEN}>>> Scripts up to date (v$LOCAL_VER).${RESET}"
        rm -rf "$TMP_DIR"
        return 0
    fi

    # 5. Update Found - Selective Backup (Exclude logs, resources, and itself)
    echo -e "${YELLOW}>>> Update found! New version: $REMOTE_VER${RESET}"
    local B_DATE=$(date +%Y%m%d_%H%M%S)
    local FULL_BACKUP_DIR="$BACKUP_BASE/ABSApplications_backup_$B_DATE"
    
    echo -e "${BLUE}>>> Creating selective backup at $FULL_BACKUP_DIR...${RESET}"
    mkdir -p "$FULL_BACKUP_DIR"

    # Copy only the essential directories
    for sub in bin config cert; do
        if [[ -d "$BASE_DIR/ABSApplications/$sub" ]]; then
            echo "   -> Backing up $sub..."
            cp -a "$BASE_DIR/ABSApplications/$sub" "$FULL_BACKUP_DIR/"
        fi
    done

    # RETENTION POLICY: Keep only last 5 backups
    local BACKUP_COUNT=$(ls -1d "$BACKUP_BASE"/ABSApplications_backup_* 2>/dev/null | wc -l)
    if [ "$BACKUP_COUNT" -gt 5 ]; then
        echo -e "${YELLOW}>>> Cleaning up old backups (Retention: 5)...${RESET}"
        # Sort by time (newest first) and delete starting from the 6th
        ls -1dt "$BACKUP_BASE"/ABSApplications_backup_* | tail -n +6 | xargs rm -rf
    fi

    # 6. Download and Extract Zip
    echo -e "${BLUE}>>> Downloading update package...${RESET}"
    wget -q --show-progress -O "$TMP_DIR/ABSApplications.zip" "$REMOTE_ZIP"
    mkdir -p "$TMP_DIR/extracted"
    unzip -oq "$TMP_DIR/ABSApplications.zip" -d "$TMP_DIR/extracted"
    
    # 7. Apply Updates (Full replacement of .sh files)
    echo -e "${BLUE}>>> Applying updates...${RESET}"
    
    # Update Master Script itself
    [[ -f "$TMP_DIR/extracted/absapps_menu.sh" ]] && cp -f "$TMP_DIR/extracted/absapps_menu.sh" "$0"
    
    # Update ALL .sh files in bin (Overwrites existing and adds new ones)
    if [[ -d "$TMP_DIR/extracted/ABSApplications/bin" ]]; then
        cp -f "$TMP_DIR/extracted/ABSApplications/bin"/*.sh "$BASE_DIR/ABSApplications/bin/" 2>/dev/null
    fi
    
    # Update Sample Config and Version INI
    cp -f "$TMP_DIR/extracted/ABSApplications/config"/sample_*.cfg "$BASE_DIR/ABSApplications/config/" 2>/dev/null
    
    cp -f "$TMP_DIR/new_version.ini" "$VERSION_FILE"

    # 8. Permissions and Restart
    dos2unix "$0" "$BASE_DIR/ABSApplications/bin"/*.sh &>/dev/null
    chmod 750 "$0"
    chmod 750 "$BASE_DIR/ABSApplications/bin"/*.sh
    
	chmod -R 775 "$TMP_DIR"
    rm -rf "$TMP_DIR"
    echo -e "${GREEN}>>> Update successful. Restarting menu...${RESET}"
    sleep 2
    exec bash "$0" "$@"
}

# Run update check before anything else
check_for_updates
# Standardized function to handle script execution
run_app_script() {
    local script_path="$1"
    local app_name="$2"
    local sel_cust="$3"
    local sel_slot="$4"

    if [[ -f "$script_path" ]]; then
        echo -e "${BLUE}>>> Preparing environment and initializing $app_name...${RESET}"
        export GLOBAL_SCRIPT_VERSION="$SCRIPT_VERSION"

        # FIX: Clean the entire bin directory so sub-scripts (like cert generator) work
        local bin_dir=$(dirname "$script_path")
        chmod -R 755 "$bin_dir"
        
        # Use find to dos2unix all .sh files in that bin folder at once
        find "$bin_dir" -name "*.sh" -exec dos2unix {} + &>/dev/null
        
        echo -e "${BLUE}>>> Launching setup for $sel_cust (Slot $sel_slot)...${RESET}"
        bash "$script_path" "$sel_cust" "$sel_slot"
    else
        echo -e "${RED}Error: $(basename "$script_path") not found.${RESET}"
        read -p "Press Enter to return to menu..."
    fi
}

# Function to list environments from the config file
list_environments() {
    clear
    # Header in GREEN
    echo -e "${GREEN}*** ABS Laundry Business Solutions ***${RESET}"
    echo -e "--- ABSApplications_menu Script - Release ${YELLOW}03.2026${RESET} - version ${YELLOW}v${SCRIPT_VERSION}${RESET}"
    echo "--- System's Date: $(date)"
    echo ""
    echo "Available ABSSolute Environment Clusters:"
    echo "----------------------------------------"
    # Column Headers
    printf "%-4s %-15s %-10s %-20s\n" "#" "Environment" "Slot" "Servers"

    # --- MODIFICATION: Only pass files to awk that actually exist ---
    local TARGET_FILES=""
    [[ -f "$CONFIG_FILE" ]] && TARGET_FILES+="$CONFIG_FILE "
    [[ -f "$INF_CONFIG" ]] && TARGET_FILES+="$INF_CONFIG "

    if [[ -z "$TARGET_FILES" ]]; then
        echo -e "${RED}Start configuring the .cfg files from sample.${RESET}"
		echo -e "${RED}No config files found.($CONFIG_FILE or $INF_CONFIG).${RESET}"
        exit 1
    fi

    # Extract unique Customer + Slot combinations from existing files
    mapfile -t ENV_LIST < <(awk '$1 !~ /^[#:]/ && NF > 0 {
        key=$1 "|" $2; 
        if (nodes[key] == "") nodes[key]=$3; 
        else if (index(nodes[key], $3) == 0) nodes[key]=nodes[key] "," $3
    } END { for (k in nodes) print k "|" nodes[k] }' $TARGET_FILES 2>/dev/null | sort)

    if [[ ${#ENV_LIST[@]} -eq 0 ]]; then
        echo -e "${RED}No environments found in config files.${RESET}"
        exit 1
    fi

    # Numbering starts from 1
    local idx=1
    for line in "${ENV_LIST[@]}"; do
        IFS="|" read -r CUST SLOT NODES <<< "$line"
        printf "%d)  ${GREEN}%-15s${RESET} %-10s ${GREEN}%s${RESET}\n" "$idx" "$CUST" "$SLOT" "$NODES"
        ((idx++))
    done
    
    echo ""
    read -rp "Select Environment number (or Press Enter to Exit): " ENV_CHOICE

    if [[ -z "$ENV_CHOICE" ]]; then exit 0; fi
    
    if [[ ! "$ENV_CHOICE" =~ ^[0-9]+$ ]] || [[ "$ENV_CHOICE" -lt 1 ]] || [[ "$ENV_CHOICE" -gt ${#ENV_LIST[@]} ]]; then
        echo -e "${RED}Invalid selection.${RESET}"
        sleep 1
        return 1
    fi

    SELECTED_ENV="${ENV_LIST[$((ENV_CHOICE-1))]}"
    IFS="|" read -r SEL_CUST SEL_SLOT SEL_NODES <<< "$SELECTED_ENV"
    
    show_app_menu "$SEL_CUST" "$SEL_SLOT"
}

# Function to show only apps registered for the selected environment
show_app_menu() {
    local cust=$1
    local slot=$2

    while true; do
        clear
        echo "|---------------------------------------------------------------------------------------"
        echo "| ABSSolute Master Application Control Center Menu                                      "
        echo "| Release Date: 03.2026                                                                 "
        echo -e "| Dedicated for ABSSolute Slot Management -  script version ${YELLOW}v${SCRIPT_VERSION}${RESET}                         "
        echo -e "| ${GREEN}Environment: $cust (Slot $slot) (Servers $SEL_NODES)${RESET}                       "
        echo "| Config: $(basename "$CONFIG_FILE" 2>/dev/null || echo "N/A") & $(basename "$INF_CONFIG" 2>/dev/null || echo "N/A")"
        echo "|---------------------------------------------------------------------------------------"
        echo "===================================="

        # --- MODIFICATION: Reset flags and check files before grepping ---
        local HAS_MOB="no" HAS_API="no" HAS_MAG="no" HAS_INF="no"

        # 1. Detection Logic for Standard Apps (only if file exists)
        if [[ -f "$CONFIG_FILE" ]]; then
            grep -qE "^$cust[[:space:]]+$slot[[:space:]]+.*MGW" "$CONFIG_FILE" && HAS_MOB="yes"
            grep -qE "^$cust[[:space:]]+$slot[[:space:]]+.*API" "$CONFIG_FILE" && HAS_API="yes"
            grep -qE "^$cust[[:space:]]+$slot[[:space:]]+.*MAG" "$CONFIG_FILE" && HAS_MAG="yes"
        fi
        
        # 2. Detection Logic for Infinity (only if file exists)
        if [[ -f "$INF_CONFIG" ]]; then
            grep -qE "^$cust[[:space:]]+$slot[[:space:]]+.*INF" "$INF_CONFIG" && HAS_INF="yes"
        fi

        local count=0
        declare -A menu_map

        # Populate Menu
        if [[ "$HAS_MOB" == "yes" ]]; then
            ((count++))
            echo "$count) Manage ABS Mobile Gateway"
            menu_map[$count]="MOB"
        fi
        if [[ "$HAS_API" == "yes" ]]; then
            ((count++))
            echo "$count) Manage ABS API Gateway"
            menu_map[$count]="API"
        fi
        if [[ "$HAS_MAG" == "yes" ]]; then
            ((count++))
            echo "$count) Manage ABS Message Agent"
            menu_map[$count]="MAG"
        fi
        if [[ "$HAS_INF" == "yes" ]]; then
            ((count++))
            echo "$count) Manage ABS Infinity (Nginx/Web)"
            menu_map[$count]="INF"
        fi

        if [[ $count -eq 0 ]]; then
            echo -e "${RED}No registered applications found for this slot.${RESET}"
        fi

        echo ""
        echo "Press Enter to return to Environment List"
        echo "===================================="
        read -rp "Choose an option (1-$count): " choice

        if [[ -z "$choice" ]]; then return; fi

        case ${menu_map[$choice]} in
            "MOB") run_app_script "$BASE_DIR/ABSApplications/bin/mobilegateway_install.sh" "Mobile Gateway" "$cust" "$slot" ;;
            "API") run_app_script "$BASE_DIR/ABSApplications/bin/APIGateway_install.sh" "API Gateway" "$cust" "$slot" ;;
            "MAG") run_app_script "$BASE_DIR/ABSApplications/bin/messageagent_install.sh" "Message Agent" "$cust" "$slot" ;;
            "INF") run_app_script "$BASE_DIR/ABSApplications/bin/nginx_Infinity_deploy.sh" "Infinity Nginx" "$cust" "$slot" ;;
            *) echo -e "${RED}Invalid option.${RESET}" ; sleep 1 ;;
        esac
    done
}

# Run loop
while true; do
    list_environments
done