#!/bin/bash

EXIT_SUCCESS=0
EXIT_ERROR=1
EXIT_INVALID_ARGS=2

# -----------------------------------------------------------------------------
print_usage_and_exit() {
    echo
    echo "Usage: $this_script [options] <A|B>"
    echo
    echo -e "\tThis script will validate a software image using the MD5 or"
    echo -e "\tSHA256 manifest."
    echo
    echo "Options:"
    echo -e "\t--help     shows this message"
    echo
    exit $EXIT_INVALID_ARGS
}

# -----------------------------------------------------------------------------
log_msg()
{
    local _level="$1"
    local _msg="$2"

    printf "%-5s: %s\n" "$_level" "$_msg"
}

# -----------------------------------------------------------------------------
error_exit()
{
    local _msg="$1"
    local _exit_code="$2"

    if [ -z "$_exit_code" ] ; then
        _exit_code="$EXIT_ERROR"
    fi

    log_msg ERROR "$_msg"

    exit $_exit_code
}

# -----------------------------------------------------------------------------
# main script
#

# Take note of our name as invoked
this_script=$(basename $0)

# handle options
while :; do
    case "$1" in
        "--help"|"-h"|"-?"|"help") print_usage_and_exit ;;
        *) break ;;
    esac
done

# get positional arguments
target_bank=$1

if [ "$#" -eq "0" ] ; then
    log_msg ERROR "missing target image partition"
    print_usage_and_exit
fi

case ${target_bank} in
    'A' | 'B' ) ;;
    *) error_exit "invalid target bank \"$target_bank\"" $EXIT_INVALID_ARGS
esac

if [ -r "/mnt/image${target_bank}/MANIFEST_SHA256" ] ; then
    (cd /mnt/image${target_bank}; sha256sum -c MANIFEST_SHA256)
    [ "$?" != "0" ] && error_exit "MANIFEST_SHA256 check failed"

elif [ -r "/mnt/image${target_bank}/MANIFEST" ] ; then
    (cd /mnt/image${target_bank}; md5sum -c MANIFEST)
    [ "$?" != "0" ] && error_exit "MANIFEST check failed"

else
    error_exit "no manifest in /mnt/image${target_bank}"
fi

if [ ! -d "/mnt/ramfs${target_bank}" ] ; then
    exit $EXIT_SUCCESS
fi

# If we get to this point, we are on an LVM capable system.  There is a corner
# case where the system has not converted to an LVM rootfs.

root_mount=$(mount | grep ' / ')
root_device=${root_mount%% *}
if [[ $root_device =~ /dev/mmcblk0p[0-9] ]] ; then
    # The root device doesn't look like an LVM, so assume that the
    # previous checks were sufficient.
    exit $EXIT_SUCCESS
fi

mount | grep -q /mnt/ramfs${target_bank}
if [ "$?" -ne "0" ] ; then
    mount /mnt/ramfs${target_bank}
    [ "$?" != "0" ] && error_exit "failed to mount /mnt/ramfs${target_bank}"
    unmount_required=1
fi

fail_count=0
(cd /mnt/ramfs${target_bank}; sha256sum -c MANIFEST_SHA256)
[ "$?" != "0" ] && fail_count=1

if [ -n "$unmount_required" ] ; then
    umount /mnt/ramfs${target_bank}
fi

if [ "$fail_count" -ne "0" ] ; then
    exit $EXIT_ERROR
fi

exit $EXIT_SUCCESS
