#!/usr/bin/env bash
RETVAL=0

MACHINE_TYPE=`uname -m`

# TODO: Add support for 64bit OTEL Collector in future versions
#  when available using the check ${MACHINE_TYPE} == 'x86_64'

OTEL_COLLECTOR_BINARY=${AM_HOME}/otel-collector/linux/32/otel-collector

USE_PORTABLE_FUNCS=0

if which dpkg > /dev/null 2> /dev/null
then
    . /lib/lsb/init-functions
    pidopts="-p $PIDFILE"
else
    if [ -f /etc/rc.d/init.d/functions ]; then
        # Source function library.
        . /etc/rc.d/init.d/functions
        # Determine if we can use the -p option to daemon, killproc, and status.
        # RHEL < 5 can't.
        if status | grep -q -- '-p' 2>/dev/null; then
            pidopts="-p $PIDFILE"
        fi
    else
        USE_PORTABLE_FUNCS=1
    fi
fi

# Reload the *.yml config files
get_config_args() {
    find "${AM_CONFIG_PIPELINES}" -name '*.yml' -exec printf '--config=%s ' {} \; | tail -n +1
}

do_startOtelCollector() {
    if isOtelCollectorServiceInstalled; then
        shutdown_otel
    fi
    config=$(get_config_args)
    $OTEL_COLLECTOR_BINARY $config 2>> ${AM_HOME}/logs/otel-collector.err &
    OTEL_PID=$!

    # Wait a moment for the process to start
    sleep 1

    if ps -p $OTEL_PID > /dev/null 2>&1; then
        echo "OtelCollector started with PID: $OTEL_PID"
    else
        echo "Error: OtelCollector failed to start"
        exit 1
    fi

    echo $OTEL_PID > $PIDFILE
}

do_stopOtelCollector() {
    if isOtelCollectorServiceInstalled; then
        shutdown_otel
    fi
    if [[ -f "$PIDFILE" ]]; then
        if pgrep -F $PIDFILE > /dev/null 2>&1; then # This will check the return code of the `pgrep` command
            # Kill child processes if any
            pgrep -P "$(head -n 1 "$PIDFILE")" | xargs -r kill -9
            if [[ $USE_PORTABLE_FUNCS -eq 1 ]]; then
                kill_process_by_pidfile "$PIDFILE"
            else
                killproc $pidopts $PIDFILE
            fi
            RETVAL=$?
            echo
            [ $RETVAL = 0 ] && rm -f ${PIDFILE}
        else
            rm -f ${PIDFILE}
        fi
    fi
}

do_restartOtelCollector() {
    do_stopOtelCollector
    if [ $? -ne 0 ]; then
        return 1
    fi
    do_startOtelCollector
}

check_both_status() {
    echo "Checking status of OtelCollector and DirectoryWatcher"
    
    # Determine PID file locations based on service installation status
    if isOtelCollectorServiceInstalled; then
        PIDFILE_BASE_DIR=/etc/otel-collector
    else
        PIDFILE_BASE_DIR=${AM_HOME}
    fi

    if isDirectoryWatcherServiceInstalled; then
        PIDFILE_DW_BASE_DIR=/etc/directory-watcher
    else
        PIDFILE_DW_BASE_DIR=${AM_HOME}
    fi

    # Set PID file paths
    PIDFILE=${PIDFILE_BASE_DIR}/am-agent.pid
    PIDFILE_DW=${PIDFILE_DW_BASE_DIR}/directory-watcher.pid

    # Check OTEL Collector status
    if [[ -f "$PIDFILE" ]]; then
        OTEL_PID=$(cat $PIDFILE)
        if [[ -n "$OTEL_PID" ]] && [[ "$OTEL_PID" =~ ^[0-9]+$ ]]; then
            if ps -p $OTEL_PID | grep otel-collector | grep -v grep > /dev/null 2>&1; then
                echo "OtelCollector is running with PID: $OTEL_PID"
            else
                echo "OtelCollector is not running"
            fi
        else
            echo "Invalid OTEL PID in $PIDFILE: '$OTEL_PID'"
        fi
    else
        echo "OTEL PID file not found at: $PIDFILE"
    fi

    # Check DirectoryWatcher status
    if [[ -f "$PIDFILE_DW" ]]; then
        DW_PID=$(cat $PIDFILE_DW)
        if [[ -n "$DW_PID" ]] && [[ "$DW_PID" =~ ^[0-9]+$ ]]; then
            if ps -p $DW_PID -o args= -ww | grep -q "com.mulesoft.dias.mule.agent.DirectoryWatcher" > /dev/null 2>&1; then
                echo "DirectoryWatcher is running with PID: $DW_PID"
            else
                echo "DirectoryWatcher is not running"
            fi
        else
            echo "Invalid DirectoryWatcher PID in $PIDFILE_DW: '$DW_PID'"
        fi
    else
        echo "DirectoryWatcher PID file not found at: $PIDFILE_DW"
    fi
}

check_status() {
    if [[ -f "$PIDFILE" ]]; then
        pgrep -F $PIDFILE
    else
        return 1
    fi
}

do_test() {
    $OTEL_COLLECTOR_BINARY $(get_config_args)
}

startDirectoryWatcher() {
    stopDirectoryWatcher
    # Check if Java is available in JAVA_HOME
    if [[ -z "$JAVA_HOME" ]]; then
        echo "Error: JAVA_HOME is not set"
        exit 1
    fi
    
    if [[ ! -x "$JAVA_HOME/bin/java" ]]; then
        echo "Error: Java is not available in JAVA_HOME: $JAVA_HOME"
        exit 1
    fi
    
    # Check Java version (optional but recommended)
    JAVA_VERSION=$("$JAVA_HOME/bin/java" -version 2>&1 | head -n 1 | cut -d'"' -f2)
    echo "Using Java version: $JAVA_VERSION from JAVA_HOME: $JAVA_HOME"
    
    # Determine execution context
    if isDirectoryWatcherServiceInstalled; then
        # Service execution (via ExecStart) - use systemd journal
        echo "Service execution mode - logging to systemd journal"
        echo "Use journalctl -u am-directory-watcher.service to see the logs"
        "$JAVA_HOME/bin/java" -D"muleHome=$HOME_DIR" -cp "${AM_HOME}/lib/*" com.mulesoft.dias.mule.agent.DirectoryWatcher &
    else
        echo "Process execution mode - logging to files ${AM_HOME}/logs/directorywatcher.log and ${AM_HOME}/logs/directorywatcher.err"
        "$JAVA_HOME/bin/java" -D"muleHome=$HOME_DIR" -cp "${AM_HOME}/lib/*" com.mulesoft.dias.mule.agent.DirectoryWatcher >> "${AM_HOME}/logs/directorywatcher.log" 2>> "${AM_HOME}/logs/directorywatcher.err" &
    fi
    
    DW_PID=$!
    
    # Wait a moment for the process to start
    sleep 1
    
    # Verify the process is running
    if ps -p $DW_PID > /dev/null 2>&1; then
        echo "DirectoryWatcher started with PID: $DW_PID"
        
        if isDirectoryWatcherServiceInstalled; then
            # Check if there's an existing PID file from previous setup.sh call
            if [[ -f "${AM_HOME}/directory-watcher.pid" ]]; then
                EXISTING_PID=$(cat "${AM_HOME}/directory-watcher.pid")
                echo "Found existing PID file at ${AM_HOME}/directory-watcher.pid with PID: $EXISTING_PID"
                
                # Verify if the existing process is still running and is DirectoryWatcher
                if ps -p $EXISTING_PID > /dev/null 2>&1; then
                    # Check if it's actually a DirectoryWatcher Java process
                    if ps -p $EXISTING_PID -o args= -ww | grep -q "com.mulesoft.dias.mule.agent.DirectoryWatcher"; then
                        echo "Existing DirectoryWatcher process found and verified. Migrating PID file..."
                        
                        # Create service directory and move PID file
                        sudo mkdir -p /etc/directory-watcher
                        echo $EXISTING_PID | sudo tee $PIDFILE_DW > /dev/null
                        
                        # Remove the old PID file
                        rm -f "${AM_HOME}/directory-watcher.pid"
                        
                        echo "PID file migrated to $PIDFILE_DW"
                        echo "DirectoryWatcher is already running with PID: $EXISTING_PID"
                        return 0
                    else
                        echo "Existing process is not DirectoryWatcher. Removing stale PID file."
                        rm -f "${AM_HOME}/directory-watcher.pid"
                    fi
                else
                    echo "Existing process is not running. Removing stale PID file."
                    rm -f "${AM_HOME}/directory-watcher.pid"
                fi
            fi
            
            # No existing valid PID file, start new DirectoryWatcher
            sudo mkdir -p /etc/directory-watcher
            echo $DW_PID | sudo tee $PIDFILE_DW > /dev/null
        else
            echo $DW_PID > $PIDFILE_DW
        fi
    else
        echo "Error: DirectoryWatcher failed to start"
        exit 1
    fi
}

stopDirectoryWatcher() {
    if [[ -f "$PIDFILE_DW" ]]; then
        PID=$(cat $PIDFILE_DW)
        if pgrep -F $PIDFILE_DW > /dev/null 2>&1; then
            if isDirectoryWatcherServiceInstalled; then
                sudo kill -TERM $PID > /dev/null 2>&1
            else
                kill -TERM $PID > /dev/null 2>&1
            fi
            sleep 2
            if pgrep -F $PIDFILE_DW > /dev/null 2>&1; then
                if isDirectoryWatcherServiceInstalled; then
                    sudo kill -KILL $PID > /dev/null 2>&1
                else
                    kill -KILL $PID > /dev/null 2>&1
                fi
            fi
        fi
        if isDirectoryWatcherServiceInstalled; then
            sudo rm -f $PIDFILE_DW
        else
            rm -f $PIDFILE_DW
        fi
    else
        echo "DirectoryWatcher PID file not found"
    fi
}



# Portable replacement for killproc
# Using kill -0 to check if kill has the permission to kill the process
# https://unix.stackexchange.com/a/169899  
kill_process_by_pidfile() {
    local pidfile="$1"
    if [[ -f "$pidfile" ]]; then
        local pid
        pid=$(head -n 1 "$pidfile")
        if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]] && kill -0 "$pid" 2>/dev/null; then
            kill "$pid"
            sleep 2
            if kill -0 "$pid" 2>/dev/null; then
                kill -9 "$pid"
            fi
            echo "Killed process $pid"
        else
            echo "No running process with PID $pid"
        fi
        rm -f "$pidfile"
    else
        echo "PID file $pidfile does not exist"
    fi
}
