#!/bin/sh

BASE="/mnt/onboard/.adds/kobo-sideload-sync"
FBINK="$BASE/third-party/fbink/bin/fbink"
FBINK_LIB_DIR="$BASE/third-party/fbink/lib"
ACK_IMAGE="$BASE/assets/start-acknowledgement.png"
DIAGNOSTIC_LOG="$BASE/run/start-feedback.log"
DIAGNOSTIC_TMP="$BASE/run/.start-feedback.log.tmp"
MAX_WAIT_TENTHS=10
WAIT_TENTHS="${KSS_START_ACK_WAIT_TENTHS:-$MAX_WAIT_TENTHS}"

if [ -r "$BASE/action-timing.sh" ]; then
    . "$BASE/action-timing.sh"
else
    kss_timing_event() { :; }
fi

kss_timing_event start_feedback_begin

if [ -f "$BASE/universal-candidate.txt" ]; then
    # New FBInk is a self-contained executable (no private libfbink.so).
    # The bounded renderer queries current geometry; it never changes rotation.
    /bin/sh "$BASE/device-preflight.sh" --basic >/dev/null 2>&1 || exit 0
    if "$BASE/bin/kobo-receiver" --device-ack=start >/dev/null 2>&1; then
        kss_timing_event start_feedback_ok
    else
        kss_timing_event start_feedback_fail
    fi
    exit 0
fi

record_feedback_failure() {
    failure_reason="$1"
    failure_exit_code="$2"
    case "$failure_reason" in
        preflight_fbink|preflight_library|preflight_image|fbink_exit|timeout) ;;
        *) failure_reason="unknown" ;;
    esac
    case "$failure_exit_code" in
        ''|*[!0-9]*) failure_exit_code="na" ;;
    esac
    umask 077
    mkdir -p "$BASE/run" 2>/dev/null || return 0
    if printf 'v1 reason=%s exit_code=%s\n' "$failure_reason" "$failure_exit_code" > "$DIAGNOSTIC_TMP" 2>/dev/null; then
        mv -f "$DIAGNOSTIC_TMP" "$DIAGNOSTIC_LOG" 2>/dev/null || :
    fi
    rm -f "$DIAGNOSTIC_TMP" 2>/dev/null || :
}

clear_feedback_failure() {
    rm -f "$DIAGNOSTIC_TMP" "$DIAGNOSTIC_LOG" 2>/dev/null || :
}

clear_feedback_failure

# This is only an immediate acknowledgement. It must never replace or bypass
# the durable lease gate that follows it in NickelMenu.
if [ ! -x "$FBINK" ]; then
    record_feedback_failure preflight_fbink 126
    kss_timing_event start_feedback_fail
    exit 0
fi
if [ ! -r "$FBINK_LIB_DIR/libfbink.so.1" ]; then
    record_feedback_failure preflight_library 126
    kss_timing_event start_feedback_fail
    exit 0
fi
if [ ! -s "$ACK_IMAGE" ]; then
    record_feedback_failure preflight_image 66
    kss_timing_event start_feedback_fail
    exit 0
fi

case "$WAIT_TENTHS" in
    ''|*[!0-9]*) WAIT_TENTHS="$MAX_WAIT_TENTHS" ;;
esac
if [ "$WAIT_TENTHS" -lt 1 ]; then
    WAIT_TENTHS=1
elif [ "$WAIT_TENTHS" -gt "$MAX_WAIT_TENTHS" ]; then
    WAIT_TENTHS="$MAX_WAIT_TENTHS"
fi

LD_LIBRARY_PATH="$FBINK_LIB_DIR${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH
"$FBINK" -q -f -w -i "$ACK_IMAGE" -g halign=CENTER,valign=CENTER >/dev/null 2>&1 &
fbink_pid=$!

attempt=0
while kill -0 "$fbink_pid" 2>/dev/null && [ "$attempt" -lt "$WAIT_TENTHS" ]; do
    attempt=$((attempt + 1))
    sleep 0.1
done

if kill -0 "$fbink_pid" 2>/dev/null; then
    kill "$fbink_pid" 2>/dev/null || :
    sleep 0.1
    kill -9 "$fbink_pid" 2>/dev/null || :
    wait "$fbink_pid" 2>/dev/null || :
    record_feedback_failure timeout 124
    kss_timing_event start_feedback_timeout
else
    wait "$fbink_pid" 2>/dev/null
    fbink_result=$?
    if [ "$fbink_result" -eq 0 ]; then
        kss_timing_event start_feedback_ok
    else
        record_feedback_failure fbink_exit "$fbink_result"
        kss_timing_event start_feedback_fail
    fi
fi

exit 0
