#!/bin/bash

# This script guarantees that only one instance of a specified Python job runs simultaneously, captures its standard and error output in timestamped log files, and notifies a monitoring endpoint when errors occur.
# The following conditional branch checks whether at least one positional argument has been provided; if not, usage information is printed and the script terminates with exit status 1.
if [ "$#" -lt 1 ]; then

    # The echo command prints usage instructions when no job file is supplied.
    echo "Usage: $0 <jobfilename> [arguments...]"

    # The script terminates with exit status 1 when the required argument is missing.
    exit 1
fi

# The variable “jobname” stores the first positional argument as the Python job file name.
jobname="$1"

# The shift statement removes the first positional argument so that any additional arguments remain accessible.
shift

# The variable “WORKDIR” defines the directory where the Python job files reside.
WORKDIR="/maui/commands"

# The variable “LOG_ROOT” defines the root directory where log folders will be created.
LOG_ROOT="/maui/logs"

# The variable “job_base” extracts the base name of the job without its extension.
job_base=$(basename "$jobname" .py)

# The variable “LOG_DIR” composes the path to the job-specific log directory.
LOG_DIR="$LOG_ROOT/$job_base"

# The mkdir command ensures that the root log directory and the job-specific directory exist, creating them if necessary.
mkdir -p "$LOG_DIR"

# The find command removes log files older than twenty-four hours (1 440 minutes) from the job-specific directory.
find "$LOG_DIR" -type f -mmin +1440 -delete

# The variable “current_pid” stores the process identifier of the currently running wrapper instance.
current_pid=$$

# The variable “wrapper_name” stores the file name of this wrapper to exclude it from the process search.
wrapper_name=$(basename "$0")

# The variable “pattern” stores the exact command signature that identifies a running job process.
pattern="python3 $jobname"

# The variable “running” captures the process identifiers that match the command signature while excluding grep and wrapper processes.
running=$(ps ax -o pid,cmd | grep "$pattern" | grep -v grep | grep -v "$wrapper_name" | awk '{print $1}')

# The following conditional branch checks whether at least one matching process identifier was found; if a job is already running, the script informs the user and terminates with exit status 0.
if [ -n "$running" ]; then

    # The echo command informs the user that the requested job is already running.
    echo "Job '$jobname' läuft bereits (PID(s): $running). Abbruch."

    # The script terminates with exit status 0 to prevent a second instance from starting.
    exit 0
fi

# The variable “timestamp” records the current date and time in YYYYMMDD-HHMMSS format.
timestamp=$(date "+%Y%m%d-%H%M%S")

# The variable “STDOUT_LOG” composes the full path to the log file for standard output.
STDOUT_LOG="$LOG_DIR/L_${timestamp}.txt"

# The variable “ERROR_LOG” composes the full path to the log file for error output.
ERROR_LOG="$LOG_DIR/E_${timestamp}.err"

# The cd command changes into the working directory or aborts with an error message if the directory is inaccessible.
cd "$WORKDIR" || { echo "Arbeitsverzeichnis $WORKDIR nicht erreichbar." >&2; exit 1; }

# The python3 command executes the specified job, redirecting standard output and error output to dedicated log files.
python3 "$jobname" "$@" > "$STDOUT_LOG" 2> "$ERROR_LOG"

# The following conditional branch checks whether the error log file contains data; if errors exist, the job name and error content are posted to the monitoring endpoint.
if [ -s "$ERROR_LOG" ]; then

    # The variable “payload” concatenates the job name and error log content for notification.
    payload="$jobname : $(<"$ERROR_LOG")"

    # The curl command posts the payload to the ntfy.sh endpoint for error reporting.
    curl -s -X POST https://ntfy.sh/itmaxDebug -d "$payload"
fi
