#!/bin/sh

PROG=$(basename $0 .sh)

# TODO compile path into swupdate
KEYFILE="/etc/swupdate-cafile.pem"

# needed in case of very low connection, DSD-1192
MAX_RETRIES=10

. /etc/rescue-system/machine.conf

RESCUE_TOOLS_DIR="//usr/share/rescue-system"
. $RESCUE_TOOLS_DIR/common-paths.env
. $RESCUE_TOOLS_DIR/rescue-lib.sh

read MACHINE HW_REVISION < /etc/hwrevision

usage() {
echo "\
Name:
  $PROG - passing a url argument to swupdate made easy

Usage:
  $PROG [options]
Options:
  -h
     Show this help message.
  -u <url>
     download swu file with http
  -i <image file>
     path to image on filesystem
  -r
     perform a factory reset
  -n
     no signature verication

 Exit codes:
   0:  Success.
  >0:  Error.
"
}

# TODO swupdate error messages are not fine grained
# example is taken from reflash-rootfs usage
# echo "   0:  Success."
# echo "   1:  Invalid arguments."
# echo "   2:  Invalid configuration file."
# echo "   3:  Unwritable target device."
# echo "   4:  Image fetch or validation failed. Reflash not attempted."
# echo "   5:  Reflashing failed. Rootfs invalidated."

IMAGE_URL=""
IMAGE_FILE=""
FACTORY_RESET=""
SKIP_VERIFICATION=""

while getopts "hru:i:n" option; do
    case $option in
        r) FACTORY_RESET="1";;
        u) IMAGE_URL="$OPTARG";;
        i) IMAGE_FILE="$OPTARG";;
        n) SKIP_VERIFICATION="1";;
        h)
            usage
            exit 0
            ;;
        \?)
            usage
            exit 1
            ;;
    esac
done

shift $((OPTIND - 1))

if [ -z "${IMAGE_URL}${IMAGE_FILE}${FACTORY_RESET}" ]; then
    echo "[ERROR] update url missing"
    exit 1
elif [ -n "$IMAGE_URL" ] && [ -n "$IMAGE_FILE" ]; then
    echo "[ERROR] network/file source can not be used together"
    exit 1
elif [ -n "${IMAGE_URL}${IMAGE_FILE}" ] && [ -n "$FACTORY_RESET" ]; then
    echo "ERROR: Options -r and -u/i are exclusive"
    exit 1
fi

if [ ! -z "$FACTORY_RESET" ]; then
    # if we've extracted the url we can just continue as if we started with -u option
    IMAGE_URL=$(awk -F= '/SWUPDATE_IMAGE_URL/ {print $2}' $DEFAULT_REFLASH_CONFIG_FILE)
fi

run_swupdate() {
    if [ -z "$SKIP_VERIFICATION" ]; then
        swupdate -L -l7 -k $KEYFILE "$@" 2>&1
        return $?
    else
        swupdate -L -l7 --disable-verification "$@" 2>&1
        return $?
    fi
}

# 22766, cpio failure if update is streamed
# also apply for 23062 and possible root cause 22491
http_prefetch_install() {
    local _url="$1"
    local _tmpdir=$(mktemp -d)
    # making it local always produces a $? of zero
    _curl_output=$(curl --output $_tmpdir/update.swu $_url 2>&1)
    local _curl_code="$?"
    local _retries=0

    logger -s -- "Prefetch image $_url"

    # try to continue a few times if connection fails, DSD-1192
    while [ "$_curl_code" -ne 0 ] && [ $_retries -lt $MAX_RETRIES ]; do
        _curl_output=$(curl -c --output $_tmpdir/update.swu $_url 2>&1)
        _curl_code="$?"
        _retries=$((++_retries))
    done

    if [ "$_curl_code" -ne 0 ]; then
        log_multiline "$_curl_output"
        return 1
    fi

    logger -s -- "Installing prefetched image"

    if ! run_swupdate -i $_tmpdir/update.swu; then
        rm -rf $_tmpdir
        return 1
    fi
    return 0
}

# NOTE getopt:
# when using quotation marks(") getopt will preserve the space between
# parameter and optarg. The download option needs quotation marks to pass
# '-u url' argument as a single optarg-argument

dss11-ledd-client system_update_started

RET=0
if [ -n "$IMAGE_URL" ]; then
    # use logger to avoid race condition
    logger -s -- "Attempting to download and install given image"
    # '-u url' is the argument of -d option, ticks are needed
    case $MACHINE in
        dss11-1gb-t1|dss11-1gb|dss11-sdc)
            # scarce on RAM and sdc also on MTD
            run_swupdate -d "-u $IMAGE_URL"
            RET=$?
            ;;
        dss20|dssip|dss11e)
            if [ -n "$USE_SWU_HTTP_DOWNLOAD" ]; then
                # partially revert: 9fa397e1a3f7
                # CAUTION: swupdate will exit with success even if installation fails,
                #   only returns an error if http fetching fails
                run_swupdate -d "-u $IMAGE_URL"
                RET=$?
            else
                http_prefetch_install $IMAGE_URL
                RET=$?
            fi
            ;;
    esac
elif [ -n "$IMAGE_FILE" ]; then
    run_swupdate -i $IMAGE_FILE
    RET=$?
fi

dss11-ledd-client system_update_completed

exit $RET
