#!/usr/bin/env bash
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set -e
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Function to __log messages with timestamp
__log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >"$RUNNERS_LOG_DIR/runners" 2>&1; }
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Function to cleanup child processes on exit
__cleanup() {
	__log "Shutting down runners..."
	kill $(jobs -p) 2>/dev/null || true
	wait
	__log "All runners stopped"
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Set up signal handling
trap __cleanup SIGTERM SIGINT
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Validate required environment variables
if [ -n "$SERVER_ADDRESS" ]; then
	if ! echo "$SERVER_ADDRESS" | grep -q '://'; then
		SERVER_ADDRESS="http://$SERVER_ADDRESS"
	fi
else
	SERVER_ADDRESS=http://$HOSTNAME
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if [ -z "$SERVER_TOKEN" ]; then
	__log "ERROR: SERVER_TOKEN environment variable is required"
	exit 1
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RUNNER_LABELS="${RUNNER_LABELS:-ubuntu-latest:docker://node:16-bullseye,ubuntu-22.04:docker://node:16-bullseye}"
# Determine number of runners to start
RUNNERS_COUNT=${RUNNERS_ENABLE:-1}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Validate RUNNERS_COUNT is a positive integer
if ! [[ "$RUNNERS_COUNT" =~ ^[0-9]+$ ]] || [ "$RUNNERS_COUNT" -lt 1 ]; then
	__log "WARNING: Invalid RUNNERS_ENABLE value '$RUNNERS_ENABLE', defaulting to 1"
	RUNNERS_COUNT=1
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
__log "Starting $RUNNERS_COUNT act_runner instance(s)"
__log "Server Address: $SERVER_ADDRESS"
__log "Runner Name Prefix: ${RUNNER_NAME_PREFIX:-runner}"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Function to start a single runner
__start_runner() {
	local runner_id=$1
	local runner_name="${RUNNER_NAME_PREFIX:-runner}-${runner_id}"
	local runner_dir="/config/act_runner/reg/${runner_name}"

	# Create runner directory
	mkdir -p "$runner_dir"
	[ -d "$runner_dir" ] && cd "$runner_dir" || return 1

	if [ ! -f "$runner_dir/.runner" ]; then
		__log "Registering runner: $runner_name (ID: $runner_id)"
		# Register the runner (this creates the .runner file)
		act_runner register --instance "$SERVER_ADDRESS" --token "$SERVER_TOKEN" --name "$runner_name" --labels "$RUNNER_LABELS" --no-interactive
		if [ $? -ne 0 ]; then
			__log "ERROR: Failed to register runner $runner_name"
			return 1
		fi
	fi
	# Start the daemon
	__log "Starting daemon for runner: $runner_name"
	exec act_runner daemon --config "$runner_dir/.runner"
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Start runners in background
for i in $(seq 1 $RUNNERS_COUNT); do
	(__start_runner $i) &
	sleep 2 # Small delay between starting runners
done
unset i
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RUNNERS_ID="$(jobs -p | tr '\n' ' ')"
if [ -n "$RUNNERS_ID" ]; then
	__log "All $RUNNERS_COUNT runners started successfully"
	__log "Process IDs: $RUNNERS_ID"
	printf 'All %s runners started successfully: %s\n' "$RUNNERS_COUNT" "$RUNNERS_ID"
else
	__log "The runners have failed to start"
	printf '%s\n' "The runners have failed to start"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Wait for all background processes
wait
