#!/bin/sh

################################################################################
#      This file is part of LibreELEC - https://libreelec.tv
#      Copyright (C) 2016 kszaq (kszaquitto (at) gmail.com)
#      Copyright (C) 2017 Paolo Rampino (liadserv (at) gmail.com)
#
#  LibreELEC is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 2 of the License, or
#  (at your option) any later version.
#
#  LibreELEC is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with LibreELEC.  If not, see <http://www.gnu.org/licenses/>.
################################################################################

IMAGE_KERNEL="/flash/kernel.img"
IMAGE_SYSTEM="/flash/SYSTEM"
IMAGE_DTB="/flash/dtb.img"
REMOTE_CONF="/tmp/remote.conf"
BACKUP_DATE=$(date +%Y%m%d%H%M%S)
SBF="/storage/backup"
BACKUP="Android-Firmware-Backup-$BACKUP_DATE"
BACKUP_FOLDER="$SBF/$BACKUP"
NOFOUND="not found "

backup_to_sd() {
  
  if grep /flash /proc/mounts | grep -q system; then
    echo you can\'t backup from internal
    exit 0
  else
    test -e $BACKUP_FOLDER || mkdir -p $BACKUP_FOLDER
    if grep -q /dev/system /proc/mounts ; then
      echo "Unmounting SYSTEM partiton."
      umount -f /dev/system
    fi
    if [ -e /dev/dtb ] ; then
      echo -n "Backup device tree..."
      dd if="/dev/dtb" status=none | gzip > "$BACKUP_FOLDER/dtb.img.gz" && sync
      echo "done."
      else
      echo "not found dtb partion or backup"
      NOFOUND=$NOFOUND" "'dtb partion or its backup'
    fi

    if [ -e /dev/recovery ] ; then
      echo -n "Backup recovery partition..."
      dd if="/dev/recovery" status=none | gzip > "$BACKUP_FOLDER/recovery.img.gz"  && sync
      echo "done."
      else
      echo "not found recovery partion or backup"
      NOFOUND=$NOFOUND" "'recovery partion or its backup'
    fi
    
    if [ -e /dev/boot ] ; then
      echo -n "Backup boot partition..."
      dd if="/dev/boot" status=none | gzip > "$BACKUP_FOLDER/boot.img.gz" && sync
      echo "done."
      else
      echo "not found boot partion or backu"
      NOFOUND=$NOFOUND" "'boot partion or its backup'
    fi
    if [ -e /dev/system ] ; then
      echo -n "Backup system partition (it requires time, be patient)..."
      dd if="/dev/system" status=none | gzip > "$BACKUP_FOLDER/system.img.gz" && sync
      echo "done."
      else
      echo "not found system partion or its backup"
      NOFOUND=$NOFOUND" "'system partion or its backup'
    fi
    if [ -e /dev/data ] ; then
       echo -n "Backup data partition (it requires long time, be more patient)..."
       dd if="/dev/data" status=none | gzip > "$BACKUP_FOLDER/data.img.gz" && sync
       echo "done."
       else
       echo "not found data partion or backup"
       NOFOUND=$NOFOUND" "'data partion or its backup'
    fi
    echo "All done! You can find the backup files in the backup share as $BACKUP,"
    echo "if you use ssh in $SBF as $BACKUP, "
    if [ "$NOFOUND" != "not found " ]; then 
    	echo -e "Warning! Missed:"$NOFOUND"\nRestore may fail!"
    fi
  fi
}

restore_to_nand() {
  
  if grep /flash /proc/mounts | grep -q system; then
    echo you can\'t restore from internal
    exit 0
  else
    if grep -q /dev/system /proc/mounts ; then
      echo "Unmounting SYSTEM partiton."
      umount -f /dev/system
    fi
    if [ -e /dev/dtb -a -e "$1/dtb.img.gz" ] ; then
      echo -n "Restore device tree..."
      zcat "$1/dtb.img.gz" | dd of="/dev/dtb" status=none && sync
      echo "done."
      else
      echo "not found /dev/dtb"
      NOFOUND=$NOFOUND" "'/dev/dtb'
    fi

    if [ -e /dev/recovery -a -e "$1/recovery.img.gz" ] ; then
      echo -n "Restore recovery partition..."
      zcat "$1/recovery.img.gz" | dd of="/dev/recovery" status=none && sync
      echo "done."
      else
      echo "not found /dev/recovery"
      NOFOUND=$NOFOUND" "'/dev/recovery'
    fi
    
    if [ -e /dev/boot -a -e "$1/boot.img.gz" ] ; then
      echo -n "Restore boot partition..."
      zcat "$1/boot.img.gz" | dd of="/dev/boot" status=none && sync
      echo "done."
      else
      echo "not found /dev/boot"
      NOFOUND=$NOFOUND" "'/dev/boot'
    fi
    if [ -e /dev/system -a -e "$1/system.img.gz" ] ; then
      echo -n "Restore system partition (it requires time, be patient)..."
      zcat "$1/system.img.gz" | dd of="/dev/system" status=none && sync
      echo "done."
      else
      echo "not found /dev/system"
      NOFOUND=$NOFOUND" "'/dev/system'
    fi
    if [ -e /dev/data -a -e "$1/data.img.gz" ] ; then
      echo -n "Restore data partition (it requires long time, be more patient)..."
      zcat "$1/data.img.gz" | dd of="/dev/data" status=none && sync
      echo "done."
      else
      echo "not found /dev/data"
      NOFOUND=$NOFOUND" "'/dev/data'
    fi
    echo "All done!"
    if [ "$NOFOUND" != "not found " ]; then 
    	echo -e "Warning! Something went wrong: "$NOFOUND
    fi
  fi
}

install_to_nand() {
  if [ -f $IMAGE_KERNEL -a -f $IMAGE_SYSTEM ] ; then
    fw_setenv upgrade_step 2

    if grep -q /dev/system /proc/mounts ; then
      echo "Unmounting SYSTEM partiton."
      umount -f /dev/system
    fi
    mkdir -p /tmp/system

    mount -o rw,remount /flash
    if [ -e /dev/dtb ] ; then
      echo -n "Backup device tree..."
      dd if="/dev/dtb" of="/flash/dtb$BACKUP_DATE.img" status=none && sync
      echo "done."
    fi

    if [ -e /dev/recovery ] ; then
      echo -n "Backup recovery partition..."
      dd if="/dev/recovery" of="/flash/recovery$BACKUP_DATE.img" bs=64K status=none && sync
      echo "done."
    fi

    if [ ! -f "/tmp/remote.conf" ] ; then
      echo -n "Backup remote.conf..."
      mount -o ro /dev/system /tmp/system
      if [ -f /tmp/system/remote.conf ]; then
        cp /tmp/system/remote.conf /tmp/remote.conf
      elif [ -f /tmp/system/etc/remote.conf ]; then
        cp -PR /tmp/system/etc/remote.conf /tmp/remote.conf
      fi
      umount /tmp/system
      echo "done."
    fi

    echo -n "Writing kernel image..."
    dd if="$IMAGE_KERNEL" of="/dev/boot" bs=64K status=none && sync
    echo "done."

    echo -n "Formatting SYSTEM partition..."
    mke2fs -F -q -t ext4 -m 0 /dev/system > /dev/null
    e2fsck -n /dev/system &> /dev/null
    echo "done."

    echo -n "Copying SYSTEM files..."
    mount -o rw /dev/system /tmp/system
    cp $IMAGE_SYSTEM /tmp/system && sync
    umount /tmp/system
    echo "done."

    if [ -f $IMAGE_DTB ] ; then
      echo -n "Writing device tree image..."
      dd if="$IMAGE_DTB" of="/dev/dtb" bs=262144 status=none && sync
      echo "done."
    fi

    echo -n "Formatting DATA partition..."
    mke2fs -F -q -t ext4 -m 0 /dev/data > /dev/null
    e2fsck -n /dev/data &> /dev/null
    echo "done."

    if [ -f "/tmp/remote.conf" ] ; then
      echo -n "Restoring remote.conf..."
      mount -o rw /dev/system /tmp/system
      cp /tmp/remote.conf /tmp/system/remote.conf
      umount /tmp/system
      echo "done."
    fi

    read -p "Do you want to copy your user data to internal data partition? [Y/n] " choice
    case "$choice" in
      [nN]*)
        ;;
      *)
        echo -n "Stopping Kodi..."
        systemctl stop kodi
        echo "done."
        echo "Copying user data..."
        mkdir -p /tmp/data
        mount -o rw /dev/data /tmp/data
        cp -av /storage/. /tmp/data/
        echo -n "Restarting Kodi..."
        systemctl start kodi
        echo "done."
        ;;
    esac

    echo "All done! You can now continue using your LE system or type \"rebootfromnand\" to reboot from internal memory."
    echo "WARNING: If your internal memory layout is different from standard Amlogic, you have to reboot and perform this operation again!"

  else
    echo "No LE image found on /flash! Exiting..."
  fi
}

if test -n "$1"
 then restore_to_nand "$1"
 exit 0
fi

echo "This script will erase BOOT, SYSTEM, DATA and DTB on your device"
echo "and install LE that you booted from SD card/USB drive."
echo ""
echo "It will create a backup of device tree and recovery partition on your boot media."
echo ""
echo "The script does not have any safeguards!"
echo ""
echo "If you want to restore old android system from backup (read below), you should re-run this script with"
echo -e "your backup folder as argument, example:\n" 
echo -e "installtointernal /storage/backup/android-backup-fold\n" 
read -p "Type \"yes\" if you know what you are doing now or type \"ba\""$'\n'"if you want to backup first the original android partitions,"$'\n'" anything else to exit: " choice
case "$choice" in
  ba) backup_to_sd ;;
  yes) install_to_nand ;;
esac
