#!/bin/bash

# globals
verbose=0     # enabled by --verbose or --dry-run
dry_run=0     # enabled by --dry-run
prompt=1      # disabled by --no-prompt
quiet=0       # enabled by --quiet
reboot=0      # enabled by --reboot

this_script=$(basename $0)
boot_mount="/mnt/boot"
new_boot_bin="/ciena/images/BOOT.BIN"
exit_code=0

# -----------------------------------------------------------------------------
print_usage_and_exit() {
    echo "Usage: $this_script [options]"
    echo
    echo -e "\tThis script will upgrade the BOOT.BIN file on an eredan system"
    echo -e "\tat $boot_mount.  By default this script will use the image at"
    echo -e "\t$new_boot_bin"
    echo
    echo "Options:"
    echo -e "\t--image <path>  upgrade to the specified file"
    echo -e "\t--verbose       displays debug information while running"
    echo -e "\t--dry-run       shows commands that will be run (but does nothing)"
    echo -e "\t--no-prompt     do not ask before upgrading"
    echo -e "\t--quiet         suppress INFO messages while running"
    echo -e "\t--reboot        reboots the system after a successful upgrade"
    echo -e "\t--help          shows this message"
    echo
    exit 1
}

# -----------------------------------------------------------------------------
msg_err() {
    local msg="$*"

    echo -e "ERROR: $msg"
}

# -----------------------------------------------------------------------------
msg_info() {
    local msg="$*"

   if [ "$quiet" -ne "1" ] ; then
        echo -e "INFO: $msg"
    fi
}

# -----------------------------------------------------------------------------
command_wrapper() {
    local command_line="$*"

    if [ "$verbose" -eq "1" ] ; then
        echo "$command_line"
    fi

    if [ "$dry_run" -eq "1" ] ; then
        return 0
    fi

    $command_line

    rc="$?"

    if [ "$rc" -ne "0" ] ; then
        msg_err "\"$command_line\" failed"
        if [ "$exit_code" -ne "0" ] ; then
            exit_code="$rc" 
        fi
    fi

    return "$rc"
}

# -----------------------------------------------------------------------------
boot_bin_version() {
    local filename="$1"

    local raw_output

    raw_output=$(/ciena/bin/bootbinExtract "$filename")

    if [ "$?" -ne "0" ] ; then
        echo -e "0\nNo version present"
    else
        echo "$raw_output"
    fi
}

# --- main --------------------------------------------------------------------

# handle options
while :; do
    case "$1" in
        "--help"|"-h"|"-?"|"help") print_usage_and_exit ;;
        "--verbose") verbose=1 ; shift ;;
        "--dry-run") verbose=1 ; dry_run=1; shift ;;
        "--image") shift ; new_boot_bin="$1" ; shift ;;
        "--no-prompt") prompt=0 ; shift ;;
        "--quiet") quiet=1 ; shift ;;
        "--reboot") reboot=1 ; shift ;;
        *) break ;;
    esac
done

if [ ! -f "$new_boot_bin" ] ; then
    msg_err "failed to find source image \"$new_boot_bin\""
    exit 1
fi

if [ ! -d "$boot_mount" ] ; then
    msg_err "failed to find directory at \"$boot_mount\""
    exit 1
fi

cur_version="$(boot_bin_version "${boot_mount}/BOOT.BIN" | head -1)"
new_version="$(boot_bin_version "$new_boot_bin" | head -1)"

if [ "$cur_version" -eq "$new_version" ] ; then
    msg_info "No need to upgrade, version $cur_version is already installed"
    exit 0
fi

if [ "$cur_version" -gt "$new_version" ] ; then
    msg_info "No need to upgrade, existing version $cur_version is newer than $new_version"
    exit 0
fi

if [ "$(whoami)" != "root" ] ; then
    msg_err "must be run as root"
    exit 1
fi

echo "upgrade from ${boot_mount}/BOOT.BIN"
echo "$(boot_bin_version "${boot_mount}/BOOT.BIN")"
echo
echo "to $new_boot_bin"
echo "$(boot_bin_version "$new_boot_bin")"
echo

if [ "$prompt" -eq "1" ] ; then
    echo " ?"
    echo -n "(y/n) "
    read -n 1 proceed
    echo
    case "$proceed" in
        [yY] ) : ;;
        *) echo "Exiting without upgrade" ; exit 0 ;;
    esac
fi

command_wrapper mount -o remount,rw $boot_mount
command_wrapper cp ${boot_mount}/BOOT.BIN ${boot_mount}/BOOT0001.BIN
command_wrapper cp $new_boot_bin ${boot_mount}/BOOT.BIN
command_wrapper rm -f ${boot_mount}/uboot.env
command_wrapper rm -f ${boot_mount}/uenvxtra.txt
command_wrapper sync
command_wrapper mount -o remount,ro $boot_mount

if [ "$reboot" -eq "1" ] ; then
    if [ "$exit_code" -eq "0" ] ; then
        # log what is happening and then force a reboot
        command_wrapper logger -s -p USER.ALERT -t $(basename $0) \
            "rebooting to activate boot image"

        # ack so that this doesn't count as a boot failure
        /ciena/scripts/bootack

        # FIX THIS
        # for now use the saros to reboot the system with a big hammer
        command_wrapper /ciena/bin/sarosreg SAROS_BRD_RESET 0xa5a5
    fi
fi

exit $exit_code
