#!/bin/bash

# Constants with default values
SCRIPT_VERSION="1.0"  # Script version to track
DOWNLOAD_BASE_URL="https://apps.digitory.com"
APP_NAME="engine_api"
TARGET_DIR="$HOME/DigiPoS"
APP_DIR="$TARGET_DIR/$APP_NAME"
LOG_FILE="$TARGET_DIR/digipos_installer.log"

# Variable to be overridden by command-line options
env="prod"
user="support"
version="latest"
file_name="${APP_NAME}@${version}.zip"

# Commands specific to the application
CMD_STOP="bin/$APP_NAME stop"
CMD_START="bin/$APP_NAME daemon"
CMD_PID="bin/$APP_NAME pid"

# Function to parse command-line options
parse_options() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
        -u | --user)
            user="$2"
            shift 2
            ;;
        -v | --version)
            version="$2"
            file_name="${APP_NAME}@${version}.zip"
            shift 2
            ;;
        *)
            log "Unknown option: $1"
            exit 1
            ;;
        esac
    done
}

# Function to download necessary files
download() {
    local download_url="${DOWNLOAD_BASE_URL}/${env}/${file_name}?sv=$SCRIPT_VERSION"

    log "Downloading $file_name from $download_url"

    # Attempt to download the file using curl with basic authentication
    if curl -# -f -u "${user}" "$download_url" -o "$TARGET_DIR/$file_name"; then
        log "Download complete: $file_name"
    else
        log "Error: Failed to download $file_name from $download_url"
        exit 1
    fi
}

# Function to check if the application is running
is_running() {
    local pid
    pid=$($CMD_PID) # Retrieves the PID of the process

    if [ -z "$pid" ]; then
        return 1 # Process is not running
    fi

    ps -p "$pid" >/dev/null 2>&1 # Checks if the process with PID exists
}

# Function to check application stop attempts for 3 times with a 5-second interval
check_stop() {
    local attempts=3
    local interval=5
    local i=0

    while [[ $i -lt $attempts ]]; do
        sleep "$interval"
        if ! is_running; then
            return 0 # Application has stopped
        fi
        ((i++))
    done

    return 1 # Application did not stop within the specified attempts
}

# Function to stop the application
stop() {
    log "Disabling cron job for DigiPoS"
    (crontab -l | sed '/autostartdigi.sh/ s/^/#/' | crontab -) || {
        log "Error: Failed to disable cron job"
        exit 1
    }
    sleep 2

    log "Stopping application..."
    $CMD_STOP

    # Wait and check application stop attempts
    if ! check_stop; then
        log "Error: Failed to stop application"
        exit 1
    fi

    log "Application stopped successfully"
}

# Function to start the application
start() {
    log "Starting application"

    $CMD_START

    sleep 5

    # Check if application started successfully
    if ! is_running; then
        log "Error: Failed to start application"
    else
        log "Application started successfully"
    fi

    # Enable cron job for DigiPoS
    log "Enabling cron job for DigiPoS"
    (crontab -l | sed '/autostartdigi.sh/ s/^#*//' | crontab -) || {
        log "Error: Failed to enable cron job"
        exit 1
    }
}

# Function to install the application
install() {
    log "Installing into $APP_DIR"

    # Clean existing directories if they exist
    rm -rf bin/ erts-*/ lib/ releases/

    # Copy downloaded zip file to application directory and unzip
    cp "$TARGET_DIR/$file_name" .
    unzip -q -o "$file_name"

    mv $APP_NAME/* . # Move contents to the application directory

    log "Installation completed"
}

# Function to perform cleanup
cleanup() {
    log "Performing cleanup"

    rm "$file_name" # Remove downloaded ZIP file

    log "Cleanup completed"
}

# Function to log messages to a file
log() {
    local message="$1"
    local timestamp
    timestamp=$(date +"%Y-%m-%d %H:%M:%S")
    local log_message="[$timestamp] User: $user - $message"
    echo "$log_message"
    echo "$log_message" >>"$LOG_FILE"
}

# Main script starts here
echo "
1) Verify and close any running shifts and sales.
2) Ensure this script is run in $HOME/DigiPoS directory.
Press 'y' or 'Y' to proceed, any other key to abort.
"

read -r proceed_choice
if [[ "$proceed_choice" != [yY] ]]; then
    log "Script execution aborted."
    exit 1
fi

# Parse command-line options
parse_options "$@"

# Start the installation process
log "Downloading $APP_NAME version $version from $DOWNLOAD_BASE_URL"
download

log "Switching to application directory: $APP_DIR"
cd "$APP_DIR" || {
    log "Error: Unable to navigate to $APP_DIR"
    exit 1
}

stop
install
start
cleanup

log "Application updated to version $version"
