#!/bin/sh

##
## Copyright 2013 Cumulus Networks, Inc.
## All rights reserved.
##

cd $(dirname $0)

archive_file=$1
shift 1

# Use busybox tools.  After linux is fully booted the busybox tools
# are available in the read-only initramfs.
initramfs_rootmnt=/mnt/initramfs
if [ -x $initramfs_rootmnt/bin/busybox ] ; then
    # This is the PowerPC way of doing things
    new_path=$initramfs_rootmnt/usr/bin:$initramfs_rootmnt/usr/sbin:$initramfs_rootmnt/bin:$initramfs_rootmnt/sbin
    PATH=${new_path}:$PATH
    SHA1SUM=sha1sum
    TAR=tar
    XZ=xz
    DD=dd
elif which busybox > /dev/null 2>&1 ; then
    SHA1SUM="busybox sha1sum"
    TAR="busybox tar"
    XZ="busybox xz"
    DD="busybox dd"
else
    echo "Error: Unable to locate busybox tools needed by installer"
    exit 1
fi

# sanity check image format - in the current directory we should see:
#
#  - control.tar.xz
#  - control.tar.xz.sha1
#  - data.tar
#
# also verify control.tar.xz.sha1

control_tar=control.tar.xz
data_tar=data.tar
[ -r "$control_tar" ] || {
    echo "Error: $control_tar is unreadable."
    exit 1
}
[ -r "${control_tar}.sha1" ] || {
    echo "Error: ${control_tar}.sha1 is unreadable."
    exit 1
}
[ -r "$data_tar" ] || {
    echo "Error: $data_tar is unreadable."
    exit 1
}
cat $control_tar | $SHA1SUM -c ${control_tar}.sha1 > /dev/null 2>&1 || {
    echo "Error: Unable to verify sha1 for $control_tar."
    exit 1
}

# open up the control archive
$XZ -d -c $control_tar | $TAR xf - || {
    echo "Error: Unable to extract $control_tar."
    exit 1
}

# source common utility functions
script_dir="$(pwd)/scripts"
. $script_dir/functions

import_kernel_cmdline
quiet=no

cmd=$1

# Protect against casual execution of the installer image
if [ -z "$cmd" ] ; then
    if [ -n "$onie_exec_url" ] ; then
        # called with no args by onie during provisioning
        cmd="provision"
    else
        # default to image info
        cmd="info"
    fi
else
    shift 1
fi

need_platform_init=
case "$cmd" in
    provision|install|env|update)
        # these operations require the running platform info
        need_platform_init=yes
        ;;
    info|extract|verify)
        # these operations do not require the running platform
        need_platform_init=no
        ;;
    *)
        log_failure_msg "Unknown installer command: $cmd"
        img=$(basename $archive_file)
        echo "Valid installer commands:"
        echo "$img info                    -- display image information"
        echo "$img verify                  -- verify image internal checksums"
        echo "$img extract <absolute path> -- extract image to path"
        exit 1
esac

# Detect the platform and load platform specific info
if [ "$need_platform_init" = "yes" ] ; then

    # compare image CPU architecture stored in the image control file
    # to the running CPU arch.
    image_arch=$(grep 'Architecture:' control | awk '{ print $2 }')
    case $(uname -m) in
        ppc)
            running_arch=powerpc
            ;;
        x86_64)
            running_arch=amd64
            ;;
        armv7l)
            running_arch=arm
            ;;
        *)
            echo "Error: Unable to determine running CPU architecture."
            exit 1
    esac
    [ "$running_arch" = "$image_arch" ] || {
        log_failure_msg "Install image target CPU architecture does not match switch CPU architecture."
        echo "  Install image target CPU architecture: $image_arch"
        echo "  Current switch CPU architecture      : $running_arch"
        echo "Please install the image file appropriate for your switch CPU architecture."
        exit 1
    }

    init_platform_path
    . $INIT_CONF/platform.conf

    # verify the current platform is listed in the "Platforms" variable.
    cl_run grep 'Platforms:' control | grep -q $platform || {
        log_failure_msg "Running platform not supported by installer image: $platform"
        exit 1
    }

fi

# source bulk of installer functions
. $script_dir/installer-functions || {
    log_failure_msg "Problem sourcing shell script: $script_dir/installer-functions"
    exit 1
}

. $script_dir/arch-installer-functions  || {
    log_failure_msg "Problem sourcing shell script: $script_dir/arch-installer-functions"
    exit 1
}

# source platform specific overrides if they exist
[ -r $script_dir/platform/${platform}_install.sh ] && . $script_dir/platform/${platform}_install.sh

# source additional overrides if they exist
[ -f $(pwd)/extra_config.sh ] && . $(pwd)/extra_config.sh

log_debug "installer: command     : $cmd"
log_debug "installer: architecture: $arch"
log_debug "installer: platform    : $platform"

case "$cmd" in
    provision)
        require_superuser
        cl_trap_ctrl_c
        image_provision_pre     "$@" || exit $?
        image_provision_handler "$@" || exit $?
        image_provision_post    "$@" || exit $?
        cl_enable_ctrl_c
        if [ "$dry_run" != "y" ] ; then
            save_info
            log_success_msg "System provisioning complete.  Rebooting..."
            reboot
        fi
        ;;
    install)
        require_superuser
        cl_trap_ctrl_c
        image_install_pre     "$@" || exit $?
        image_install_handler "$@" || exit $?
        image_install_post    "$@" || exit $?
        cl_enable_ctrl_c
        ;;
    env)
        require_superuser
        cl_trap_ctrl_c
        image_env_pre     "$@" || exit $?
        image_env_handler "$@" || exit $?
        image_env_post    "$@" || exit $?
        cl_enable_ctrl_c
        ;;
    extract)
        image_extract_pre     "$@" || exit $?
        image_extract_handler "$@" || exit $?
        image_extract_post    "$@" || exit $?
        ;;
    verify)
        image_verify_pre     "$@" || exit $?
        image_verify_handler "$@" || exit $?
        image_verify_post    "$@" || exit $?
        ;;
    info)
        image_info_pre     "$@" || exit $?
        image_info_handler "$@" || exit $?
        image_info_post    "$@" || exit $?
        ;;
    update)
        require_superuser
        cl_trap_ctrl_c
        image_update_pre "$@" || exit $?
        image_update_handler $archive_file "$@" || exit $?
        image_update_post "$@" || exit $?
        cl_enable_ctrl_c
        ;;
    *)
        log_failure_msg "Unknown installer cmd: $cmd"

esac
