#!/bin/sh
export LC_ALL="en_US.UTF-8"

PROC_KEYPAD="/proc/keypad"
PROC_FIVEWAY="/proc/fiveway"
[ -e $PROC_KEYPAD ] && echo unlock >$PROC_KEYPAD
[ -e $PROC_FIVEWAY ] && echo unlock >$PROC_FIVEWAY

# KOReader's working directory
KOREADER_DIR="/mnt/us/koreader"

# Load our helper functions...
if [ -f "${KOREADER_DIR}/libkohelper.sh" ]; then
    # shellcheck source=/dev/null
    . "${KOREADER_DIR}/libkohelper.sh"
else
    echo "Can't source helper functions, aborting!"
    exit 1
fi

# Handle logging...
logmsg() {
    # Use the right tools for the platform
    if [ "${INIT_TYPE}" = "sysv" ]; then
        msg "koreader: ${1}" "I"
    elif [ "${INIT_TYPE}" = "upstart" ]; then
        f_log I koreader wrapper "" "${1}"
    fi

    # And throw that on stdout too, for the DIY crowd ;)
    echo "${1}"
}

# Go away if we're on FW 5.0, it's not supported
if [ "${INIT_TYPE}" = "upstart" ]; then
    if grep '^Kindle 5\.0' /etc/prettyversion.txt >/dev/null 2>&1; then
        logmsg "FW 5.0 is not supported. Update to 5.1!"
        # And... scene!
        exit 0
    fi
fi

# Keep track of what we do with pillow...
export AWESOME_STOPPED="no"
PILLOW_HARD_DISABLED="no"
PILLOW_SOFT_DISABLED="no"
PASSCODE_DISABLED="no"

# Keep track of if we were started through KUAL
FROM_KUAL="no"

# By default, don't stop the framework.
if [ "$1" = "--framework_stop" ]; then
    shift 1
    STOP_FRAMEWORK="yes"
    NO_SLEEP="no"
elif [ "$1" = "--asap" ]; then
    # Start as soon as possible, without sleeping to workaround UI quirks
    shift 1
    NO_SLEEP="yes"
    STOP_FRAMEWORK="no"
    # Don't sleep during eips calls either...
    export EIPS_NO_SLEEP="true"
else
    STOP_FRAMEWORK="no"
    NO_SLEEP="no"
fi

# Detect if we were started by KUAL by checking our nice value...
if [ "$(nice)" = "5" ]; then
    FROM_KUAL="yes"
    if [ "${NO_SLEEP}" = "no" ]; then
        # Yield a bit to let stuff stop properly...
        logmsg "Hush now . . ."
        # NOTE: This may or may not be terribly useful...
        usleep 250000
    fi

    # Kindlet threads spawn with a nice value of 5, go back to a neutral value
    logmsg "Be nice!"
    renice -n -5 $$
fi

# we're always starting from our working directory
cd "${KOREADER_DIR}" || exit

# Handle pending OTA update
NEWUPDATE="${KOREADER_DIR}/ota/koreader.updated.tar"
INSTALLED="${KOREADER_DIR}/ota/koreader.installed.tar"
if [ -f "${NEWUPDATE}" ]; then
    logmsg "Updating koreader . . ."
    # Look for our own GNU tar build to do a fancy progress tracking...
    GNUTAR_BIN="${KOREADER_DIR}/tar"
    if [ -x "${GNUTAR_BIN}" ]; then
        # Let our checkpoint script handle the detailed visual feedback...
        eips_print_bottom_centered "Updating koreader" 1
        # shellcheck disable=SC2016
        ${GNUTAR_BIN} -C "/mnt/us" --no-same-owner --no-same-permissions --checkpoint=200 --checkpoint-action=exec='./kotar_cpoint $TAR_CHECKPOINT' -xf "${NEWUPDATE}"
        fail=$?
    else
        # Fall back to busybox tar
        eips_print_bottom_centered "Updating koreader . . ." 1
        tar -C "/mnt/us" -xf "${NEWUPDATE}"
        fail=$?
    fi
    # Cleanup behind us...
    if [ $fail -eq 0 ]; then
        mv "${NEWUPDATE}" "${INSTALLED}"
        logmsg "Update sucessful :)"
        eips_print_bottom_centered "Update successful :)" 1
    else
        # Huh ho...
        logmsg "Update failed :("
        eips_print_bottom_centered "Update failed :(" 1
    fi
    rm -f "${NEWUPDATE}" # always purge newupdate in all cases to prevent update loop
fi

# load our own shared libraries if possible
export LD_LIBRARY_PATH=${KOREADER_DIR}/libs:$LD_LIBRARY_PATH

# export trained OCR data directory
export TESSDATA_PREFIX="data"

# export dict directory
export STARDICT_DATA_DIR="data/dict"

# export external font directory
export EXT_FONT_DIR="/mnt/us/fonts"

# Only setup IPTables on evices where it makes sense to (FW 5.x & K4)
if [ "${INIT_TYPE}" = "upstart" ] || [ "$(uname -r)" = "2.6.31-rt11-lab126" ]; then
    logmsg "Setting up IPTables rules . . ."
    # accept input ports for zsync plugin
    iptables -A INPUT -i wlan0 -p udp --dport 5670 -j ACCEPT
    iptables -A INPUT -i wlan0 -p tcp --dport 49152:49162 -j ACCEPT
    # accept input ports for calibre companion
    iptables -A INPUT -i wlan0 -p udp --dport 8134 -j ACCEPT
fi

# bind-mount system fonts
if ! grep ${KOREADER_DIR}/fonts/host /proc/mounts >/dev/null 2>&1; then
    logmsg "Mounting system fonts . . ."
    mount -o bind /usr/java/lib/fonts ${KOREADER_DIR}/fonts/host
fi

# bind-mount altfonts
if [ -d /mnt/us/fonts ]; then
    mkdir -p ${KOREADER_DIR}/fonts/altfonts
    if ! grep ${KOREADER_DIR}/fonts/altfonts /proc/mounts >/dev/null 2>&1; then
        logmsg "Mounting altfonts . . ."
        mount -o bind /mnt/us/fonts ${KOREADER_DIR}/fonts/altfonts
    fi
fi

# bind-mount csp fonts
if [ -d /var/local/font/mnt ]; then
    mkdir -p ${KOREADER_DIR}/fonts/cspfonts
    if ! grep ${KOREADER_DIR}/fonts/cspfonts /proc/mounts >/dev/null 2>&1; then
        logmsg "Mounting cspfonts . . ."
        mount -o bind /var/local/font/mnt ${KOREADER_DIR}/fonts/cspfonts
    fi
fi

# bind-mount linkfonts
if [ -d /mnt/us/linkfonts/fonts ]; then
    mkdir -p ${KOREADER_DIR}/fonts/linkfonts
    if ! grep ${KOREADER_DIR}/fonts/linkfonts /proc/mounts >/dev/null 2>&1; then
        logmsg "Mounting linkfonts . . ."
        mount -o bind /mnt/us/linkfonts/fonts ${KOREADER_DIR}/fonts/linkfonts
    fi
fi

# check if we need to disable the system passcode, because it messes with us in fun and interesting (and, more to the point, intractable) ways...
# NOTE: The most egregious one being that it inhibits the outOfScreenSaver event on wakeup until the passcode is validated, which we can't do, since we capture all input...
if [ -f "/var/local/system/userpasswdenabled" ]; then
    logmsg "Disabling system passcode . . ."
    rm -f "/var/local/system/userpasswdenabled"
    PASSCODE_DISABLED="yes"
fi

# check if we are supposed to shut down the Amazon framework
if [ "${STOP_FRAMEWORK}" = "yes" ]; then
    logmsg "Stopping the framework . . ."
    # Upstart or SysV?
    if [ "${INIT_TYPE}" = "sysv" ]; then
        /etc/init.d/framework stop
    else
        # The framework job sends a SIGTERM on stop, trap it so we don't get killed if we were launched by KUAL
        trap "" TERM
        stop lab126_gui
        # NOTE: Let the framework teardown finish, so we don't start before the black screen...
        usleep 1250000
        # And remove the trap like a ninja now!
        trap - TERM
    fi
fi

# check if kpvbooklet was launched for more than once, if not we will disable pillow
# there's no pillow if we stopped the framework, and it's only there on systems with upstart anyway
if [ "${STOP_FRAMEWORK}" = "no" ] && [ "${INIT_TYPE}" = "upstart" ]; then
    count=$(lipc-get-prop -eiq com.github.koreader.kpvbooklet.timer count)
    if [ "$count" = "" ] || [ "$count" = "0" ]; then
        # NOTE: Dump the fb so we can restore something useful on exit...
        cat /dev/fb0 >/var/tmp/koreader-fb.dump
        # NOTE: We want to disable the status bar (at the very least). Unfortunately, the soft hide/unhide method doesn't work properly anymore since FW 5.6.5...
        # shellcheck disable=SC2046
        if [ "$(printf "%.3s" $(grep '^Kindle 5' /etc/prettyversion.txt 2>&1 | sed -n -r 's/^(Kindle)([[:blank:]]*)([[:digit:].]*)(.*?)$/\3/p' | tr -d '.'))" -ge "565" ]; then
            PILLOW_HARD_DISABLED="yes"
            # FIXME: So we resort to killing pillow completely on FW >= 5.6.5...
            logmsg "Disabling pillow . . ."
            lipc-set-prop com.lab126.pillow disableEnablePillow disable
            # NOTE: And, oh, joy, on FW >= 5.7.2, this is not enough to prevent the clock from refreshing, so, take the bull by the horns, and SIGSTOP the WM while we run...
            # shellcheck disable=SC2046
            if [ "$(printf "%.3s" $(grep '^Kindle 5' /etc/prettyversion.txt 2>&1 | sed -n -r 's/^(Kindle)([[:blank:]]*)([[:digit:].]*)(.*?)$/\3/p' | tr -d '.'))" -ge "572" ]; then
                logmsg "Stopping awesome . . ."
                killall -stop awesome
                AWESOME_STOPPED="yes"
            fi
        else
            logmsg "Hiding the status bar . . ."
            # NOTE: One more great find from eureka (http://www.mobileread.com/forums/showpost.php?p=2454141&postcount=34)
            lipc-set-prop com.lab126.pillow interrogatePillow '{"pillowId": "default_status_bar", "function": "nativeBridge.hideMe();"}'
            PILLOW_SOFT_DISABLED="yes"
        fi
        # NOTE: We don't need to sleep at all if we've already SIGSTOPped awesome ;)
        if [ "${NO_SLEEP}" = "no" ] && [ "${AWESOME_STOPPED}" = "no" ]; then
            # NOTE: Leave the framework time to refresh the screen, so we don't start before it has finished redrawing after collapsing the title bar
            usleep 250000
            # NOTE: If we were started from KUAL, we risk getting a list item to popup right over us, so, wait some more...
            # The culprit appears to be a I WindowManager:flashTimeoutExpired:window=Root 0 0 600x30
            if [ "${FROM_KUAL}" = "yes" ]; then
                logmsg "Playing possum to wait for the window manager . . ."
                usleep 2500000
            fi
        fi
    fi
fi

# stop cvm (sysv & framework up only)
if [ "${STOP_FRAMEWORK}" = "no" ] && [ "${INIT_TYPE}" = "sysv" ]; then
    logmsg "Stopping cvm . . ."
    killall -stop cvm
fi

# finally call reader
logmsg "Starting KOReader . . ."
# That's not necessary when using KPVBooklet ;).
if [ "${FROM_KUAL}" = "yes" ]; then
    eips_print_bottom_centered "Starting KOReader . . ." 1
fi

# we keep maximum 500K worth of crash log
if [ -e crash.log ]; then
    tail -c 500000 crash.log >crash.log.new
    mv -f crash.log.new crash.log
fi

RETURN_VALUE=85
while [ $RETURN_VALUE -eq 85 ]; do
    ./reader.lua "$@" >>crash.log 2>&1
    RETURN_VALUE=$?
done

# clean up our own process tree in case the reader crashed (if needed, to avoid flooding KUAL's log)
if pidof reader.lua >/dev/null 2>&1; then
    logmsg "Sending a SIGTERM to stray KOreader processes . . ."
    killall -TERM reader.lua
fi

# unmount system fonts
if grep ${KOREADER_DIR}/fonts/host /proc/mounts >/dev/null 2>&1; then
    logmsg "Unmounting system fonts . . ."
    umount ${KOREADER_DIR}/fonts/host
fi

# unmount altfonts
if grep ${KOREADER_DIR}/fonts/altfonts /proc/mounts >/dev/null 2>&1; then
    logmsg "Unmounting altfonts . . ."
    umount ${KOREADER_DIR}/fonts/altfonts
fi

# unmount cspfonts
if grep ${KOREADER_DIR}/fonts/cspfonts /proc/mounts >/dev/null 2>&1; then
    logmsg "Unmounting cspfonts . . ."
    umount ${KOREADER_DIR}/fonts/cspfonts
fi

# unmount linkfonts
if grep ${KOREADER_DIR}/fonts/linkfonts /proc/mounts >/dev/null 2>&1; then
    logmsg "Unmounting linkfonts . . ."
    umount ${KOREADER_DIR}/fonts/linkfonts
fi

# Resume cvm (only if we stopped it)
if [ "${STOP_FRAMEWORK}" = "no" ] && [ "${INIT_TYPE}" = "sysv" ]; then
    logmsg "Resuming cvm . . ."
    killall -cont cvm
    # We need to handle the screen refresh ourselves, frontend/device/kindle/device.lua's Kindle3.exit is called before we resume cvm ;).
    echo 'send 139' >/proc/keypad
    echo 'send 139' >/proc/keypad
fi

# Restart framework (if need be)
if [ "${STOP_FRAMEWORK}" = "yes" ]; then
    logmsg "Restarting framework . . ."
    if [ "${INIT_TYPE}" = "sysv" ]; then
        cd / && env -u LD_LIBRARY_PATH /etc/init.d/framework start
    else
        cd / && env -u LD_LIBRARY_PATH start lab126_gui
    fi
fi

# Display chrome bar if need be (upstart & framework up only)
if [ "${STOP_FRAMEWORK}" = "no" ] && [ "${INIT_TYPE}" = "upstart" ]; then
    # Depending on the FW version, we may have handled things in a few different manners...
    if [ "${AWESOME_STOPPED}" = "yes" ]; then
        logmsg "Resuming awesome . . ."
        killall -cont awesome
    fi
    if [ "${PILLOW_HARD_DISABLED}" = "yes" ]; then
        logmsg "Enabling pillow . . ."
        lipc-set-prop com.lab126.pillow disableEnablePillow enable
        # NOTE: Try to leave the user with a slightly more useful FB content than our own last screen...
        cat /var/tmp/koreader-fb.dump >/dev/fb0
        rm -f /var/tmp/koreader-fb.dump
        lipc-set-prop com.lab126.appmgrd start app://com.lab126.booklet.home
        # NOTE: In case we ever need an extra full flash refresh...
        #eips -s w=${SCREEN_X_RES},h=${SCREEN_Y_RES} -f
    fi
    if [ "${PILLOW_SOFT_DISABLED}" = "yes" ]; then
        logmsg "Restoring the status bar . . ."
        # NOTE: Try to leave the user with a slightly more useful FB content than our own last screen...
        cat /var/tmp/koreader-fb.dump >/dev/fb0
        rm -f /var/tmp/koreader-fb.dump
        lipc-set-prop com.lab126.pillow interrogatePillow '{"pillowId": "default_status_bar", "function": "nativeBridge.showMe();"}'
        lipc-set-prop com.lab126.appmgrd start app://com.lab126.booklet.home
    fi
fi

if [ "${INIT_TYPE}" = "upstart" ] || [ "$(uname -r)" = "2.6.31-rt11-lab126" ]; then
    logmsg "Restoring IPTables rules . . ."
    # restore firewall rules
    iptables -D INPUT -i wlan0 -p udp --dport 8134 -j ACCEPT
    iptables -D INPUT -i wlan0 -p udp --dport 5670 -j ACCEPT
    iptables -D INPUT -i wlan0 -p tcp --dport 49152:49162 -j ACCEPT
fi

if [ "${PASSCODE_DISABLED}" = "yes" ]; then
    logmsg "Restoring system passcode . . ."
    touch "/var/local/system/userpasswdenabled"
fi

exit $RETURN_VALUE
