#! /bin/bash
set -e

quiet_boot="0"
. "$pkgdatadir/grub-mkconfig_lib"

export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"

CLASS="--class gnu-linux --class gnu --class os"

boot_device_id=$GRUB_DEVICE_UUID

LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}

UPGRADER=/usr/sbin/deepin-upgrade-manager
SNAPSHOT_DIR_PREFIX=/boot/snapshot
SNAPSHOT_DIR=/snapshot

if [ "x${DEEPIN_UPGRADER_VERSION_LIMIT}" = "x" ]; then
    DEEPIN_UPGRADER_VERSION_LIMIT=3
fi

if [ ! -f ${UPGRADER} ];then
    echo "# ${UPGRADER} not found"
    exit 0
fi

lines=`${UPGRADER} --action=list || /bin/true`
while read line
do
    echo "# will parse: ${line}"
    case "$line" in
        "ActiveVersion"*)
            activeVersion=$(echo $line | awk -F ':' '{print $2}' | awk '{gsub(/^\s+|\s+$/, "");print}')
            ;;
        "AvailVersionList"*)
            availList=$(echo $line | awk -F ':' '{print $2}' | awk '{gsub(/^\s+|\s+$/, "");print}')
            availList=(${availList// / })
            ;;
    esac
done <<EOT
$lines
EOT

if [ "x${activeVersion}" = "x" ]; then
    echo "# empty active version"
    exit 0
fi

echo "# active: ${activeVersion}"
echo "# avail: ${availList[@]}"

offset=0
limit=$((${offset}+${DEEPIN_UPGRADER_VERSION_LIMIT}))

rollbackList=()
for ver in "${availList[@]}"
do
    if [ $offset -ge $limit ];then
        break
    fi

    if [ ! -d "${SNAPSHOT_DIR_PREFIX}/${ver}" ]; then
        echo "# not exists: ${SNAPSHOT_DIR_PREFIX}/${ver}, generated by: ${UPGRADER} --action=snapshot --version=${ver}"
        ${UPGRADER} --action=snapshot --version=${ver}
        if [ "$?" != "0" ]; then
            continue
        fi
    fi

    rollbackList[${offset}]=${ver}
    offset=$((1+${offset}))
done

if [ x"${#rollbackList[@]}" = x"0" ]; then
    echo "# no version to rollback"
    exit 0
fi
echo "# rollback list: ${rollbackList[@]}"

linux_entry ()
{
    title="$1"
    linux="$2"
    initrd="$3"
    args="$4"

    if [ -z "$boot_device_id" ]; then
        boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
    fi
    echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
    if [ "$quick_boot" = 1 ]; then
        echo "	recordfail" | sed "s/^/$submenu_indentation/"
    fi

  sed "s/^/$submenu_indentation/" << "EOF"
	set	boot=(${root})/boot/
EOF
    # Use ELILO's generic "efifb" when it's known to be available.
    # FIXME: We need an interface to select vesafb in case efifb can't be used.
    arch=`uname -m`
    if [ x"$arch" = x"mips64" ]; then
        need_boot=1
    fi
    if [ x$dirname = x/ ]; then
        if [ -z "${prepare_root_cache}" ]; then
            prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)"
        fi
        printf '%s\n' "${prepare_root_cache}" | sed "s/^/$submenu_indentation/"
    else
        if [ -z "${prepare_boot_cache}" ]; then
            prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
        fi
        printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
    fi
    if [ x"$quiet_boot" = x0 ]; then
        message="$(gettext_printf "Loading Linux %s ..." ${version})"
        sed "s/^/$submenu_indentation/" << EOF
	echo	'$(echo "$message" | grub_quote)'
EOF
    fi
    if test -n "${initrd}" ; then
        # TRANSLATORS: ramdisk isn't identifier. Should be translated.
        if [ x"$quiet_boot" = x0 ]; then
            message="$(gettext_printf "Loading initial ramdisk ...")"
            sed "s/^/$submenu_indentation/" << EOF
	echo	'$(echo "$message" | grub_quote)'
EOF
        fi
        sed "s/^/$submenu_indentation/" << EOF
	linux.boot	\${boot}${initrd}
EOF
    fi
  if test -f /boot/bootloader.bin ; then
      message="$(gettext_printf "Loading Linux %s ..." "bootloader.bin")"
      sed "s/^/$submenu_indentation/" << EOF
	echo	'$(echo "$message" | grub_quote)'
EOF
    sed "s/^/$submenu_indentation/" << EOF
	linux.console	\${boot}/bootloader.bin
EOF
    if [ x"$dtbo" = x1 ]; then
        if [ x"$quiet_boot" = x0 ]; then
            message="$(gettext_printf "Loading device tree image ...")"
            sed "s/^/$submenu_indentation/" << EOF
	echo	'$(echo "$message" | grub_quote)'
EOF
        fi
        sed "s/^/$submenu_indentation/" << EOF
	devicetree ${dtbo_rel_dirname}/dtbo.img
EOF
    fi

    if [ x"$need_boot" = x1 ]; then
        echo "	boot" |sed "s/^/$submenu_indentation/"
    fi
    sed "s/^/$submenu_indentation/" << EOF
EOF
  fi
  sed "s/^/$submenu_indentation/" << EOF
	linux.vmlinux	\${boot}${linux} root=${linux_root_device_thisversion} ro ${args}
EOF
  sed "s/^/$submenu_indentation/" << EOF
 	boot
EOF
  sed "s/^/$submenu_indentation/" << EOF
}
EOF
}

get_linux_image()
{
    arch="$1"
    snapshot="$2"

    case "x$arch" in
        xi?86 | xx86_64)
	        for i in ${snapshot}/vmlinuz-* ${snapshot}/kernel-* ; do
	            if test -e "$i" ; then
                    LINUX="$i"
                    break
                fi
	        done ;;
        *)
	        for i in ${snapshot}/vmlinuz-* ${snapshot}/vmlinux-*  ${snapshot}/kernel-* ; do
	            if test -e "$i" ; then
                    LINUX="$i"
                    break
                fi
	        done ;;
    esac
}

machine=`uname -m`

# disable locale if arch is mips or arm
case "x$machine" in
    xmips*)
        export LC_ALL=C
        ;;
    xaarch*)
        export LC_ALL=C
        ;;
esac

prepare_boot_cache=
prepare_root_cache=
title_correction_code=
submenu_indentation=""
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"

echo "submenu 'Deepin Rollback Advance Options' \$menuentry_id_option 'gnulinux-advanced-${boot_device_id}' {"
for rollback in "${rollbackList[@]}"
do
    SNAPSHOT_DIR="${SNAPSHOT_DIR_PREFIX}/${rollback}"
    LINUX=
    get_linux_image "${machine}" "${SNAPSHOT_DIR}"
    if [ "x${LINUX}" = "x" ]; then
        echo "# not found linux image in ${SNAPSHOT_DIR}"
        continue
    fi
    basename=`basename $LINUX`
    dirname=`dirname $LINUX`
    dtbo_dirname=`dirname $dirname`
    dtbo_rel_dirname=`make_system_path_relative_to_its_root $dtbo_dirname`

    rel_dirname=`make_system_path_relative_to_its_root $dirname`
    version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
    alt_version=`echo $version | sed -e "s,\.old$,,g"`

    if test -e "$dtbo_dirname/dtbo.img"; then
	    dtbo=1
    fi

    INITRD=
    if test -e "${SNAPSHOT_DIR}/initrd.img-${version}"; then
	    INITRD="${rel_dirname}/initrd.img-${version}"
    elif  test -e "${SNAPSHOT_DIR}/initrd.img-${alt_version}";then
        INITRD="${rel_dirname}/initrd.img-${alt_version}"
    fi
    LINUX=${rel_dirname}/${basename}
    # for i in "${SNAPSHOT_DIR}/initrd.img-${version}" "${SNAPSHOT_DIR}/initrd.img-${alt_version}"; do
    #     if test -e "$i"; then
    #         INITRD="$i"
    #         break
    #     fi
    # done
    menu_entry=$(printf "$(gettext -d deepin-upgrade-manager 'Rollback to %s')" "${rollback}")
    submenu_indentation="$grub_tab"
    linux_entry "$menu_entry" "${LINUX}" "${INITRD}" "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} back_version=${rollback}"
done
echo "}"
