#!/bin/bash
### BEGIN INIT INFO
# Provides:          nx1boot
# Required-Start:    $remote_fs loadcpufreq
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:
# X-Start-Before:    hddbootflush
# Short-Description: nx1 boot sequence
# Description:       Provides the ability to boot up automatically depending on available
#                    boot devices and ability to override boot using the boot menu.
### END INIT INFO
# VERSION: 4.0.0.29987

export NX1LOG=/var/log/nx1.log
set -x

# Close STDOUT file descriptor
exec 1<&-
# Close STDERR FD
exec 2<&-

# Open STDOUT as $NX1LOG file for read and write.
exec 1<>$NX1LOG

# Redirect STDERR to STDOUT
exec 2>&1

echo `date` "++++++++++++++++++++++ Starting Boot Process ++++++++++++++++++++++++"

export CUSTOMIZATION="networkoptix"
export DISTRIB="nxwitness-server-4.0.0.29987-bpi.tar.gz"

export CHECKBOOTHDDPART=
export CHECKDATAHDDPART=
export DISK=`fdisk -l | grep "Disk" | grep "dev/sd" | awk '{print substr ($2, 0, length($2))}'`
if [ ! -z $DISK ]; then
    export CHECKBOOTHDDPART=`fdisk -l | grep "$DISK"1 | awk '{print $1}'`
    export CHECKDATAHDDPART=`fdisk -l | grep "$DISK"2 | awk '{print $1}'`
fi

if [[ ! -z $( cat /proc/cmdline | grep mmc ) ]]; then export BOOTDEVICE=mmc; else export BOOTDEVICE=ata; fi

export BOOTHDDPART="$DISK"1
export DATAHDDPART="$DISK"2
export MAC=`ifconfig | grep eth0 | grep -v avahi | awk {'print $5'}`
export MOUNTBOOT=
export MOUNTDATA=
export HDDNX1=
export BOOTPART=/dev/mmcblk0p1
export UBOOTENVPART=/dev/mmcblk0p3
export DATAPART=/dev/mmcblk0p2
export MNTBOOTPART=/mnt/boot
export MNTUBOOTENVPART=/mnt/ubootenv
export MNTDATAPART=/mnt/data
export MNTBOOTHDDPART=/mnt/hdd/boot
export MNTDATAHDDPART=/mnt/hdd/data
export HDDBOOTFLUSHSCRIPT=hddbootflush.sh
export HDDBOOTFLUSH=/etc/init.d/$HDDBOOTFLUSHSCRIPT
export HDDBOOT_INDICATOR=$MNTUBOOTENVPART/hddboot
export TOOLS_DIR=/root/tools/$CUSTOMIZATION

LITE_CLIENT_STARTUP_SCRIPT="/etc/init.d/$CUSTOMIZATION-lite-client"

setup_hdd_environment() {
    if [ -f /tmp/hdd_native ]; then rm /tmp/hdd_native; fi
    if [ -f /tmp/archive ]; then rm /tmp/archive; fi
    if [ ! -z $CHECKBOOTHDDPART ] && [ ! -z $CHECKDATAHDDPART ]; then
        mkdir -p $MNTDATAHDDPART
        mkdir -p $MNTBOOTHDDPART
        mount -t ext4 $DATAHDDPART $MNTDATAHDDPART
        mount -t ext4 $BOOTHDDPART $MNTBOOTHDDPART
        HDDMAC=`cat $MNTBOOTHDDPART/var/tmp/mac`
        echo `date` "ACTUAL MAC:"$MAC""
        echo `date` "HARD DRIVE IS BOUND TO MAC:"$HDDMAC""
        if [ -f $MNTBOOTHDDPART/restored ] && [ -f $MNTBOOTHDDPART/boot/vmlinuz*bananian ] && [ "$HDDMAC" = "$MAC" ]; then HDDNX1=true; else HDDNX1=false; fi
        ARCHIVE_FILES=`ls $MNTDATAHDDPART/*Media/ | grep quality`
        ARCHIVE_DB=`ls $MNTDATAHDDPART/*Media/ | grep ".sqlite"`
        if [[ ! -z "$ARCHIVE_FILES" ]] && [[ ! -z "$ARCHIVE_DB" ]]; then ARCHIVE=true; else ARCHIVE=false; fi
        echo `date` "ARCHIVE FOUND ON HDD:"$ARCHIVE""
        for p in $( lsof $MNTBOOTHDDPART | grep $MNTBOOTHDDPART | awk {'print $2'} ); do kill $p; done
        sleep 2
        umount $BOOTHDDPART
        for p in $( lsof $MNTDATAHDDPART | grep $MNTDATAHDDPART | awk {'print $2'} ); do kill $p; done
        sleep 2
        umount $DATAHDDPART
        rm -Rf $MNTBOOTHDDPART
    else
        HDDNX1=false
        ARCHIVE=false
    fi
    echo $HDDNX1 > /tmp/hdd_native
    echo $ARCHIVE > /tmp/archive
}

read_hdd_environment() {
    export HDDNX1=`cat /tmp/hdd_native`
    export ARCHIVE=`cat /tmp/archive`
}

stop_server() {
    /etc/init.d/cron stop
    /etc/init.d/$CUSTOMIZATION-mediaserver stop
}

start_server() {
    /etc/init.d/cron start
    /etc/init.d/$CUSTOMIZATION-mediaserver start
}

start_lite_client() {
    if [ -f "$LITE_CLIENT_STARTUP_SCRIPT" ]; then
        "$LITE_CLIENT_STARTUP_SCRIPT" start
    fi
}

stop_lite_client() {
    if [ -f "$LITE_CLIENT_STARTUP_SCRIPT" ]; then
        "$LITE_CLIENT_STARTUP_SCRIPT" stop
    fi
}

tweak_charger() {
    #tweak to enable battery charge function for AXP209
i2cset -f -y 0 0x34 0x35 0x83
}

get_reset_button_presense() {
    mkdir -p $MNTBOOTPART
    mount -t vfat $BOOTPART $MNTBOOTPART
    ln -s $MNTBOOTPART/backup/bootloader /tmp/fw_printenv
    # Serial Number was used only for checking the reset button status. Removing old file.
    rm -rf /tmp/serial
	RESET=$(/tmp/fw_printenv reset | sed 's/reset=//')
	RESET=${RESET:-false}
    echo "++++++++++++++ RESET BUTTON PRESENT: "$RESET" ++++++++++++++" >&2 >/dev/kmsg
    echo `date` "++++++++++++++ RESET BUTTON PRESENT: "$RESET" ++++++++++++++" >> $NX1LOG
    rm /tmp/fw_printenv
    umount $BOOTPART
    rm -Rf $MNTBOOTPART
}

hddboot_indicator_flush() {
    mkdir -p $MNTUBOOTENVPART
    mount $UBOOTENVPART $MNTUBOOTENVPART
    if [ -f $HDDBOOT_INDICATOR ]; then rm $HDDBOOT_INDICATOR; fi
    umount $UBOOTENVPART
    rm -Rf $MNTUBOOTENVPART
}

#tweak to reanimate network interface after MAC change
ethtweak () {
    ETH=`ifconfig | grep eth0 | awk {'print $1'}`
    if [ -z "$ETH" ]; then
        echo `date` "NETWORK INTERFACE ERROR. REBOOTING TO FIX"
        rm /etc/udev/rules.d/70-persistent-net.rules
        reboot
    fi
}

hddboot_indicator_create() {
    mkdir -p $MNTUBOOTENVPART
    mount $UBOOTENVPART $MNTUBOOTENVPART
    if [ ! -f $HDDBOOT_INDICATOR ]; then touch $HDDBOOT_INDICATOR; fi
    umount $UBOOTENVPART
    rm -Rf $MNTUBOOTENVPART
}

reboot_from_hdd () {
    if [ -z $DISK ]; then
        echo `date` "NO HDD FOUND"
        exit 1
    else
        echo `date` "REBOOTING FROM HDD..."
        hddboot_indicator_flush
        reboot
        exit 0
    fi
}

reboot_from_sd () {
    echo `date` "REBOOTING FROM SD CARD..."
    hddboot_indicator_create
    reboot
    sleep 1
    exit 0
}

system_restore () {
    if [ -z $DISK ]; then
        echo `date` "NO HDD FOUND"
        exit 0
    fi

    if [ "$BOOTDEVICE" = "ata" ]; then
        rm /restored
        fsck.ext4 $DATAPART -fy
        mkdir -p $MNTBOOTPART
        mount -t vfat $BOOTPART $MNTBOOTPART
        if [ ! -f $MNTBOOTPART/restore ]; then touch $MNTBOOTPART/restore; fi
        umount $BOOTPART
        rm -Rf $MNTBOOTPART
        echo `date` "REBOOTING TO SD CARD FOR RESTORE"
        reboot_from_sd
        exit 0
    fi

    if [ "$BOOTDEVICE" = "mmc" ] && [ ! -f /restore ]; then
        mkdir -p $MNTBOOTHDDPART
        mount -t ext4 $BOOTHDDPART $MNTBOOTHDDPART
        rm $MNTBOOTHDDPART/restored
        umount $BOOTHDDPART
        rm -Rf $MNTBOOTHDDPART
        echo `date` "REBOOTING FOR RESTORE"
        touch /restore
        hddboot_indicator_create
        shutdown -rF now
        exit 0
    fi

    if [ -f /restore ]; then
        stop_server
        stop_lite_client
        read_hdd_environment
        /etc/init.d/nx1led restore
        rm /etc/udev/rules.d/70-persistent-net.rules
        for p in $( lsof $MNTBOOTHDDPART | grep $MNTBOOTHDDPART | awk {'print $2'} ); do kill $p; done
        sleep 2
        umount $BOOTHDDPART
        for p in $( lsof $MNTDATAHDDPART | grep $MNTDATAHDDPART | awk {'print $2'} ); do kill $p; done
        sleep 2
        umount $DATAHDDPART
        if [ "$ARCHIVE" = "false" ]; then
            echo `date` "FOREIGN HDD FOUND. FORMATTING THE WHOLE DRIVE..."
            dd if=/dev/zero of=$DISK bs=512 count=1 conv=notrunc
            (echo 2; echo x; echo z; echo y; echo y) | gdisk $DISK
            #for v_partition in $(parted -s $DISK print|awk '/^ / {print $1}')
            #do
            #   parted -s $DISK rm ${v_partition}
            #done
            (echo y) | parted -a optimal $DISK mklabel msdos
            #(echo w) | fdisk $DISK
            #parted -a optimal $DISK mkpart primary ext4 0G 8G
            (echo n; echo p; echo 1; echo ; echo +7600MB; echo w) | fdisk $DISK
            #parted -a optimal $DISK mkpart primary ext4 8G 100%
            (echo n; echo p; echo 2; echo ; echo ; echo w) | fdisk $DISK
            partprobe $DISK
            mkfs.ext4 $DATAHDDPART
            mkdir -p $MNTDATAHDDPART
            mount -t ext4 $DATAHDDPART $MNTDATAHDDPART
            MOUNTDATA=`df -h | grep "$DATAHDDPART"`
            sleep 2
            if [ -z "$MOUNTDATA" ]; then
                echo `date` "CANNOT MOUNT FILESYSTEM "$DATAHDDPART" - REBOOTING FOR RESTORE "
                touch /restore
                hddboot_indicator_create
                shutdown -rF now
                exit 0
            fi
            for p in $( lsof $MNTDATAHDDPART | grep $MNTDATAHDDPART | awk {'print $2'} ); do print $p; done
            sleep 2
            umount $DATAHDDPART
        else
            echo `date` "ARCHIVE FOUND ON HDD. RESTORING ONLY SYSTEM PARTITION..."
        fi
        echo "RESTORING SYSTEM PARTITION..."
        mkfs.ext4 $BOOTHDDPART
        mkdir -p $MNTBOOTHDDPART
        mount -t ext4 $BOOTHDDPART $MNTBOOTHDDPART
        MOUNTBOOT=`df -h | grep "$BOOTHDDPART"`
        sleep 2
        if [ -z "$MOUNTBOOT" ]; then
            echo `date` "CANNOT MOUNT FILESYSTEM "$BOOTHDDPART" - REBOOTING FOR RESTORE "
            touch /restore
            hddboot_indicator_create
            shutdown -rF now
            exit 0
        fi
        for p in $( lsof | grep $MNTBOOTHDDPART | awk {'print $2'} ); do kill $p; done
        sleep 2
        umount $BOOTHDDPART
        dd if=$DATAPART of=$BOOTHDDPART bs=4096 conv=notrunc,noerror,sync
        #rsync -arx --progress  --delete / $MNTBOOTHDDPART --exclude 'mnt' >&2 >/dev/kmsg
        sync
        #echo "/dev/sda2    /mnt/hdd/data    ext4    defaults        0       0" >> $MNTBOOTHDDPART/etc/fstab
        mount -t ext4 $BOOTHDDPART $MNTBOOTHDDPART
        rm -Rf $MNTBOOTHDDPART/mnt
        mkdir $MNTBOOTHDDPART/mnt
        mv -f $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/var/scripts $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/
        rm -Rf $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/var
        rm -Rf $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/etc/
        mkdir -p $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/etc/
        mkdir -p $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/var/
        cp -f $TOOLS_DIR/mediaserver.conf.template $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/etc
        cp -f /opt/$CUSTOMIZATION/mediaserver/var/ecs_static.sqlite $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/var
        mv -f $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/scripts $MNTBOOTHDDPART/opt/$CUSTOMIZATION/mediaserver/var
        #restoring saved IP configuration
        if [ -f /var/tmp/interfaces ] && [ -f /var/tmp/keep_ip ]; then
            cp -f /var/tmp/interfaces $MNTBOOTHDDPART/etc/network
        else
            cp -f /root/tools/network/interfaces $MNTBOOTHDDPART/etc/network
        fi
        delete_saved_ipconfig
        rm /var/tmp/interfaces
        rm /var/tmp/keep_ip
        rm $MNTBOOTHDDPART/restore
        touch $MNTBOOTHDDPART/restored
        if [ ! -f $MNTBOOTHDDPART/var/tmp/mac ]; then echo $MAC > $MNTBOOTHDDPART/var/tmp/mac; fi
        hddboot_indicator_flush
        umount $BOOTHDDPART
        /etc/init.d/nx1led stop
        shutdown -rF now
        exit 0
    fi
}

check_statistics_warning() {
    CONF_FILE="/opt/$CUSTOMIZATION/mediaserver/etc/mediaserver.conf"
    grep -q "statisticsReportAllowed=true" $CONF_FILE \
        && echo "statisticsReportAllowed=true" >> $CONF_FILE
}

save_ipconfig() {
# saves IP configuration and sets the flag to restore it after reboot (if reboot happened during restore process)
    echo `date` "SAVING IP CONFIG..."
    if [ "$BOOTDEVICE" = "mmc" ]; then
        mkdir -p $MNTBOOTHDDPART
        mount -t ext4 $BOOTHDDPART $MNTBOOTHDDPART
        if [ -f $MNTBOOTHDDPART/etc/network/interfaces ]; then
            cp -f $MNTBOOTHDDPART/etc/network/interfaces /var/tmp
        else
            cp -f /etc/network/interfaces /var/tmp
        fi
        touch /var/tmp/keep_ip
        umount $BOOTHDDPART
    fi
    if [ "$BOOTDEVICE" = "ata" ]; then
        mkdir -p $MNTDATAPART
        mount -t ext4 $DATAPART $MNTDATAPART
        cp -f /etc/network/interfaces $MNTDATAPART/var/tmp
        touch $MNTDATAPART/var/tmp/keep_ip
        umount $DATAPART
        rm -Rf $MNTDATAPART
    fi
}

delete_saved_ipconfig() {
    if [ "$BOOTDEVICE" = "mmc" ]; then
        rm /var/tmp/interfaces
        rm /var/tmp/keep_ip
    fi
    if [ "$BOOTDEVICE" = "ata" ]; then
        mkdir -p $MNTDATAPART
        mount -t ext4 $DATAPART $MNTDATAPART
        rm $MNTDATAPART/var/tmp/interfaces
        rm $MNTDATAPART/var/tmp/keep_ip
        umount $DATAPART
        rm -Rf $MNTDATAPART
    fi
}

upgrade() {
    if [ "$BOOTDEVICE" = "ata" ]; then
        if [ ! -f /var/tmp/mac ]; then echo $MAC > /var/tmp/mac; fi
    else
        mkdir -p $MNTBOOTHDDPART
        mount -t ext4 $BOOTHDDPART $MNTBOOTHDDPART
        if [ ! -f $MNTBOOTHDDPART/var/tmp/mac ]; then echo $MAC > $MNTBOOTHDDPART/var/tmp/mac; fi
        umount $BOOTHDDPART
        rm -Rf $MNTBOOTHDDPART
    fi
    get_reset_button_presense
    chown root:root /etc/crontab
    chmod 600 /etc/crontab
}

# Install all deb packages from /opt/deb/<package>/, but do nothing if the directory is missing, or
# the specified version of a deb package with the same name as the directory is already installed.
installDebs() # package [version]
{
    local -r PACKAGE="$1"; shift
    local VERSION=""
    if [ $# -ge 2 ]; then
        VERSION="$2"
    fi

    local -r DEB_DIR="/opt/deb/$PACKAGE"
    if [ ! -d "$DEB_DIR" ]; then # The deb is missing from /opt/deb.
        return
    fi

    local -r INSTALLED_VERSION=$(dpkg -l |grep "$PACKAGE" |grep "$VERSION" |awk '{print $3}')
    if [ -z "$INSTALLED_VERSION" ]; then
        dpkg -i "$DEB_DIR"/*.deb
    fi
}

# Called on booting from SD Card.
upgrade_sd() {
    # Commented out because there is no .tar.gz on sdcard anymore.
    #tar xfv /root/$DISTRIB -C / --exclude "./etc/init.d/nx1*"

    touch /dev/cedar_dev
    chmod 777 /dev/disp
    chmod 777 /dev/cedar_dev
    usermod -aG video root
    sync

    installDebs cifs-utils
    installDebs libvdpau 0.4.1
    installDebs fontconfig 2.11
    installDebs fonts-takao-mincho
    installDebs fonts-baekmuk
    installDebs fonts-arphic-ukai
}

default_sequence () {
    get_reset_button_presense
    # Upgrading sdcard on first boot.
    if [ "$BOOTDEVICE" = "mmc" ]; then upgrade_sd; fi
    if [ "$RESET" = "true" ]; then /etc/init.d/nx1button start; fi
    stop_server
    setup_hdd_environment
    echo `date` "BOOTED FROM "$BOOTDEVICE""
    ethtweak
    tweak_charger
    check_statistics_warning
    if [ "$BOOTDEVICE" = "mmc" ]; then
        if [ -z $DISK ]; then
            echo `date` "NO HDD FOUND"
            hddboot_indicator_create
        else
            if [ "$HDDNX1" = "false" ]; then
                echo `date` "FOREIGN HDD FOUND. LAUNCHING SYSTEM RESTORE..."
                system_restore
            else
                echo `date` "NX1 HDD FOUND. NEXT TIME WILL TRY TO BOOT ONE MORE TIME..."
                hddboot_indicator_flush
            fi
        fi
        /etc/init.d/nx1led boot_sd
    fi
    if [ "$BOOTDEVICE" = "ata" ]; then
        echo `date` "MOUNTING DATA HDD PARTITION..."
        mount -t ext4 $DATAHDDPART $MNTDATAHDDPART
        /etc/init.d/nx1led boot_hdd
    fi
    start_server
    start_lite_client
}

case "$1" in
  start)
    touch /forcefsck
    default_sequence
    exit 0
    ;;
  restart|reload|force-reload)
    echo "Error: argument '$1' not supported" >&2
    exit 3
    ;;
  stop)
    # No-op
    ;;
  reboot)
    shutdown -rF now
    ;;
  boot_sd)
    reboot_from_sd
    ;;
  boot_hdd)
    reboot_from_hdd
    ;;
  restore)
    delete_saved_ipconfig
    system_restore
    ;;
  restore_keep_ip)
    save_ipconfig
    system_restore
    ;;
  upgrade)
    upgrade
    ;;
  *)
    echo "Usage: nx1boot [start|stop|reboot|boot_sd|boot_hdd|restore|restore_keep_ip|upgrade]" >&2
    exit 3
    ;;
esac
