#!/bin/bash -

# Copyright (C) MOXA Inc. All rights reserved.
# This software is distributed under the terms of the MOXA SOFTWARE NOTICE.
# See the file MOXA-SOFTWARE-NOTICE for details.
#
# Name:
#	MOXA Image Auto Install Configuration Utility
#
# Description:
#	Configure and Check Auto Install Information
#
# Copyright (C) Moxa, Inc. All rights reserved.
# Copyright (C) 2021	Remus Wu	<remusty.wu@moxa.com>
# Copyright (C) 2022	Henry LC Chen	<HenryLC.Chen@moxa.com>

BASENAME="mx-image-auto-install-tool"
INTERFACE_NAME="mx-bootloader-mgmt image_auto_install"
AUTO_INSTALL_CMD=rfi_cmd

configuration_is_set() {
    local info
    info=$(fw_printenv -n $AUTO_INSTALL_CMD 2>&1)

    if grep -q "## Error:" <<<"$info"; then
        $LOGGER_ECHO "$BASENAME" "Error: configuration is not set"
        return 1
    elif [ "$info" == "" ]; then
        $LOGGER_ECHO "$BASENAME" "Error: configuration is not set"
        return 1
    fi

    return 0
}

info() {
    local info
    info=$(fw_printenv -n $AUTO_INSTALL_CMD 2>&1)

    local image_file
    image_file=$(echo "$info" | cut -d ',' -f 3)
    local disk_name
    disk_name=$(echo "$info" | awk -F ',' '{ print toupper($1) }')

    if [ "$MBM_OPTION_JSON" = "y" ]; then
        jq -n --arg image_file "${image_file}" --arg disk_name "${disk_name}" '{imageFile: $image_file, diskName: $disk_name}'
    fi

    $LOGGER_ECHO "$BASENAME" "Image auto install configuration:"
    $LOGGER_ECHO "$BASENAME" "Image File: ${image_file}"
    $LOGGER_ECHO "$BASENAME" "Disk Name: ${disk_name}"
}

configure() {
    local secure
    local dir
    local fstype
    local image
    secure=$(fw_printenv -n secure 2>&1)
    dir=$(mount | grep "$(mx-interface-mgmt disk "$DISK" | grep PARTITION_1 | cut -d= -f2)" | awk '{ print $3 }')
    fstype=$(mount | grep "$dir" | awk '{ print $5 }')
    image=$dir/$(basename "$FILE")
    local suffix=sha256sum.bin

    if [ "$(uname -m)" = "aarch64" ]; then
        suffix=sha512sum.bin
    fi
    if [ "$secure" = 1 ]; then
        suffix=${suffix}.signed
    fi

    if [ "$fstype" != "vfat" ] && [ "$fstype" != "ext4" ]; then
        $LOGGER_ECHO "$BASENAME" "Error: filesystem type $fstype is not support, required 'FAT' or 'EXT4'"
        return 1
    elif ! find "$dir" -type f -name "$(basename "$FILE")" >/dev/null; then
        $LOGGER_ECHO "$BASENAME" "Error: $FILE is not exist."
        return 1
    elif [ ! -f "$image" ]; then
        $LOGGER_ECHO "$BASENAME" "Error: $(basename "$image") is not in the root directory of $DISK"
        return 1
    elif [ ! -f "${image}".${suffix} ]; then
        $LOGGER_ECHO "$BASENAME" "Error: ${FILE}.${suffix} is not exist"
        return 1
    fi

    # fw_setenv rfi_cmd 'usb,1,FWR_UC-3100_develop.img'
    # fw_setenv rfi_cmd 'sd,1,FWR_UC-3100_develop.img'
    fw_setenv $AUTO_INSTALL_CMD "${DISK,,},1,$(basename "$image")"
    info
}

parsing_options() {
    if ! OPTS=$(getopt -o d:f:irhJ --long disk:,file:,info,remove,help,json -n "$INTERFACE_NAME" -- "$@"); then
        $HELPER_MENU "wrong" "image_auto_install"
        exit "${?}"
    fi
    eval set -- "$OPTS"

    while [ -n "$1" ]; do
        case "$1" in
        -d | --disk)
            if [ -n "$DISK" ]; then
                return 1
            fi
            DISK="$2"
            shift 2
            ;;
        -i | --info)
            if [ -n "$ACTION" ]; then
                return 1
            fi
            ACTION=info
            shift
            ;;
        -J | --json)
            export MBM_OPTION_JSON=y
            shift
            ;;
        -f | --file)
            if [ -n "$FILE" ]; then
                return 1
            fi
            FILE="$2"
            shift 2
            ;;
        -r | --remove)
            if [ -n "$ACTION" ]; then
                return 1
            fi
            ACTION=remove
            shift
            ;;
        -h | --help)
            $HELPER_MENU "image_auto_install"
            exit "${?}"
            ;;
        --)
            shift
            break
            ;;
        *)
            shift
            break
            ;;
        esac
    done

    if [ -z "$ACTION" ]; then
        if [ -z "$FILE" ]; then
            echo "Error: image name is not set"
            return 1
        elif [ -z "$DISK" ]; then
            echo "Error: disk name is not set"
            return 1
        elif ! mx-interface-mgmt disk "$DISK" >/dev/null; then
            echo "Error: incorrect disk name '$DISK'"
            return 1
        elif [ "$(mx-interface-mgmt disk "$DISK" | grep NUMBER_OF_PARTITIONS | cut -d= -f2)" != 1 ]; then
            echo "Error: '$DISK' has more than one partition"
            return 1
        elif ! mount | grep -q "$(mx-interface-mgmt disk "$DISK" | grep PARTITION_1 | cut -d= -f2)"; then
            echo "Error: disk '$DISK' is not mount"
            return 1
        fi
        ACTION=configure
    fi

    return 0
}

main() {
    if ! parsing_options "$@"; then
        $HELPER_MENU "wrong" "image_auto_install"
        exit "${?}"
    fi

    case "$ACTION" in
    configure)
        if ! configuration_is_set >/dev/null; then
            configure || return 1
        else
            $LOGGER_ECHO "$BASENAME" "Warning: configuration has been set"
            info
            return 1
        fi
        ;;
    info)
        if configuration_is_set; then
            info
        else
            $LOGGER_ECHO "$BASENAME" "Warning: configuration is not set"
            return 1
        fi
        ;;
    remove)
        if configuration_is_set; then
            fw_setenv $AUTO_INSTALL_CMD
            if ! configuration_is_set >/dev/null; then
                $LOGGER_ECHO "$BASENAME" "Configuration is clear."
            else
                $LOGGER_ECHO "$BASENAME" "Error: configuration clear failed."
                return 1
            fi
        fi
        ;;
    *) ;;
    esac

    return 0
}

main "$@"
exit "$?"
