#!/bin/bash
#process that uses this system backup script
# - lh_mtc.py

MYTH_RUN_STATUS="1"
. /etc/profile
. /etc/systemconfig
PLEXDIR=/var/lib/plex
KeepBackups=14
DATE=`date +%F_%H-%M`
backup_status=0
MYTHHOME=`lh_home_check.sh`
MYTHSHUTDOWN="/usr/bin/mythshutdown"

#find primary backup location
for dir in /data/storage/disk*
do
    if [ $dir == /data/storage/disk0 ]; then
        continue
    fi
    TESTDIR=`readlink $dir`
    if [ -n $TESTDIR ]; then
        BACKUPLINK=$dir
        BACKUPDISK=$TESTDIR
        BACKUPDIR=$TESTDIR/backup/system_backups
        break
    fi
done

if ! mountpoint -q "$BACKUPDISK"; then
    echo "    The system doesn't have a second drive. Backup skipped."
    exit $backup_status
fi


#find secondary backup location
for dir in /data/storage/disk*
do
    if [[ $dir == /data/storage/disk0 || $dir == $BACKUPLINK ]]; then
        continue
    fi
    TESTDIR=`readlink $dir`
    if [ -n $TESTDIR ]; then
        SECBACKUPLINK=$dir
        SECBACKUPDISK=$TESTDIR
        SECBACKUPDIR=$TESTDIR/backup/system_backups
        break
    fi
done

function lock_myth(){
    $MYTHSHUTDOWN --lock
}

function unlock_myth(){
    $MYTHSHUTDOWN --unlock
}

function backup_status_check(){
    if [ $1 -ne 0 ]
    then
        backup_status=1
    fi
}


function backup(){

    echo
    echo "Starting Backup"
    echo "Backup Directory: $BACKUPLINK --> $BACKUPDIR"
    echo "Secondary Backup Directory: $SECBACKUPLINK --> $SECBACKUPDIR"
    echo
    mkdir -p $BACKUPDIR/$DATE

    #backup database
    if [ $SystemType = MasterBackend -o $SystemType = Standalone ]
    then
        echo
        echo "Backup mariadb databases"
        pacman -Q mysql 2>/dev/null
        if [ $? = 0 ]
        then
            echo "    mythconverg  (mythtv database)"
            /usr/bin/mariadb-dump -x mythconverg > $BACKUPDIR/$DATE/mythconverg
            backup_status_check $?

            #this is everything
            echo "    All databases in one file"
            /usr/bin/mariadb-dump -x --all-databases > $BACKUPDIR/$DATE/all_databases
            backup_status_check $?
        fi
    fi

    echo "Backup saved settings"
    if [ -e  /usr/MythVantage/templates/settings ]
    then
        cp -rp  /usr/MythVantage/templates/settings $BACKUPDIR/$DATE/settings
        backup_status_check $?
    fi

    echo "Backup etc"
    cp -rp /etc  $BACKUPDIR/$DATE/etc

    echo "Backup Plex Media Server databases and preferences"
    if [ -e $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support ]
    then
        mkdir $BACKUPDIR/$DATE/plex
        backup_status_check $?
    fi
    if [ -e  $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Databases ]
    then
        mkdir -p $BACKUPDIR/$DATE/plex/Databases/
        backup_status_check $?
        cp -rp $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Databases/*.db $BACKUPDIR/$DATE/plex/Databases/
        backup_status_check $?
        cp -rp $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Databases/*.db-wal $BACKUPDIR/$DATE/plex/Databases/
        backup_status_check $?
        cp -rp $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Databases/*.db-shm $BACKUPDIR/$DATE/plex/Databases/
        backup_status_check $?
    fi
    if [ -e  $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Preferences ]
    then
        cp -rp $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Preferences $BACKUPDIR/$DATE/plex/Preferences
        backup_status_check $?
    fi

    #create default backup_exclude.txt
    if [ ! -f $MYTHHOME/backup_config/backup_exclude.txt ]
    then
        mkdir -p $MYTHHOME/backup_config/
        touch $MYTHHOME/backup_config/backup_exclude.txt
        chmod 777 $MYTHHOME/backup_config/backup_exclude.txt
    fi

    for i in ".mythtv/cache" ".mythtv/themecache" ".mythtv/remotecache" ".mythtv/Cache-myth*" ".cache" "tmp" ".vnc/*log" ".vnc/*pid" ".plexht/userdata/Thumbnails" ".plexht/userdata/ThemeMusicCache" ".kodi/userdata/Thumbnails"
    do
        grep -qF "$i" $MYTHHOME/backup_config/backup_exclude.txt
        rc=$?
        if [ $rc != 0 ]
        then
            echo "$i" >> $MYTHHOME/backup_config/backup_exclude.txt
        fi
    done

    echo "Backup home dirs"
    HOMEDIRS=""
    tar -I pigz -cf $BACKUPDIR/$DATE/home_dir.tar.gz -X $MYTHHOME/backup_config/backup_exclude.txt  $MYTHHOME $HOMEDIRS

    if [ -f $MYTHHOME/backup_config/backup_include.txt ]
    then
        echo
        echo "Backup items from $MYTHHOME/backup_config/backup_include.txt"
        tar -I pigz -cf $BACKUPDIR/$DATE/other.tar.gz -T $MYTHHOME/backup_config/backup_include.txt
        backup_status_check $?
    fi

    echo "Compress backup file"
    cd $BACKUPDIR
    tar -I pigz -cf $BACKUPDIR/backup.$DATE.tgz  $DATE
    backup_status_check $?
    if [ -d $BACKUPDIR/$DATE ]
    then
        rm -rf $BACKUPDIR/$DATE
    fi

    if [ $backup_status -eq 0 ]
    then
        BACKUPPATH=$BACKUPDIR/backup.$DATE.tgz
    else
        echo "Backup had an error"
        mkdir $BACKUPDIR/errored_backups
        mv $BACKUPDIR/backup.$DATE.tgz $BACKUPDIR/errored_backups/backup.$DATE.tgz
        BACKUPPATH=$BACKUPDIR/errored_backups/backup.$DATE.tgz
    fi

    if [ -f /home/xymon/server/ext/hbnotes.py ]
    then
        /home/xymon/server/ext/hbnotes.py
        chown nobody:nobody /data/srv/httpd/htdocs/hobbit/notes/* 2> /dev/null >/dev/null
    fi
    echo
    echo "Created backup file:"
    echo "    $BACKUPPATH"
}

function update_backup_status(){
    echo
    # Add Last backup status to menu item
    #if description not in the backup xml file, add it
    if [ $rc=0 ]
    then
        COMPLETE_MSG="Last backup completed `date '+%D %-I:%M %p'`"
    else
        COMPLETE_MSG="Last backup FAILED `date '+%D %-I:%M %p'`"
    fi
    echo "Updating menu with:"
    echo "    $COMPLETE_MSG"
    xmlfile="/usr/share/mythtv/themes/defaultmenu/mythbackup.xml"

    grep  -q "<description>" $xmlfile >/dev/null
    desc_check=$?

    if [ $desc_check = 0 ]
    then
        sed -i "0,/<description\>.*\<description\>/s||\<description\>$COMPLETE_MSG<\/description|" $xmlfile
        #sed -i "0,/\<description\>.*\<description\>/s//\<description\>$COMPLETE_MSG\<\/description/" $xmlfile
    else
        sed -i " /NONE/ i\     \<description\>$COMPLETE_MSG\<\/description\>" $xmlfile
    fi
}

function remove_old_backups(){
    #remove old backups
    NumBackups=`ls $BACKUPDIR/backup*.tgz|wc -l`
    if [[ $NumBackups -gt  $KeepBackups ]]; then
        numdel=$(($NumBackups-$KeepBackups))
        rm -f `ls $BACKUPDIR/backup*.tgz -tr1|head -$numdel`
    fi
}


function remote_backup(){
    echo
    echo "Remote backup"
    #Remote copy
    if [ x$RemoteBackup = x1 ]
    then
        localRemoteCheck=`echo $RemoteBackupDir | cut -d: -f1`
        if [  x$localRemoteCheck =  xdir ]
        then
            localRemotedir=`echo $RemoteBackupDir | cut -d: -f2`
            echo "    copying $BACKUPDIR/backup.$DATE.tgz to  $localRemotedir  "
            cp $BACKUPDIR/backup.$DATE.tgz  $localRemotedir
        else
            /usr/bin/func  ${RemoteBackupDir}  ping| grep -q "FAILED"
            rc=$?
            if [ $rc = 0 ]
            then
                #this is here to mark failed copy of the backup.
                #There is a cron.hourly job that will attempt to retransfer the file
                echo "    Remote backup failed to ${RemoteBackupDir}"
                echo backup.$DATE.tgz >> $BACKUPDIR/remote_backup_failed.txt
            else
                echo "    copying $BACKUPDIR/backup.$DATE.tgz to  ${RemoteBackupDir}:$BACKUPDIR/MBE_$DATE.tgz"
                /usr/bin/func  ${RemoteBackupDir} copyfile  -f  $BACKUPDIR/backup.$DATE.tgz  --remotepath $BACKUPDIR/MBE_$DATE.tgz
            fi
        fi
    else  #do local copy to SECBACKUPLINK
        echo "    Remote backup is not enabled, copying backup to another drive on this system."

        if [ -n "$SECBACKUPDISK" ]; then
            SECBACKUP=$SECBACKUPDISK/backup
            if [ ! `mountpoint -q $SECBACKUPDISK 2> /dev/null` ]; then
                if [ ! -d "$SECBACKUPDIR" ]; then
                    mkdir -p -m 775 $SECBACKUPDIR
                    echo "    Created $SECBACKUPDIR"
                    chown mythtv:users $SECBACKUPDIR
                fi
                echo "    Copying system backups to $SECBACKUPDIR"
                rsync -au --delete $BACKUPDIR/ $SECBACKUPDIR/
            else
                echo "    $SECBACKUPDISK isn't mounted."
            fi
        else
            echo "    Could not find another drive on this system."
        fi
    fi
}

function remote_transfer(){
    transfer_file=${1}
    echo $transfer_file
    /usr/bin/func  ${RemoteBackupDir}  ping| grep -q "FAILED"
    rc=$?
    if [ $rc = 0 ]
    then
        #this is here to mark a failed copy of the backup.
        #There is a cron.hourly job that will attempt to retransfer the file
        echo "    Remote backup failed to ${RemoteBackupDir}"
        echo $transfer_file >> $BACKUPDIR/remote_backup_failed.txt
    else
        echo "    copying $BACKUPDIR/$transfer_file to  ${RemoteBackupDir}:$BACKUPDIR/MBE_$transfer_file"
        /usr/bin/func  ${RemoteBackupDir} copyfile  -f  $BACKUPDIR/$transfer_file  --remotepath $BACKUPDIR/MBE_$transfer_file
    fi
}

function add_link(){
    if [ -f $BACKUPDIR/remote_backup_failed.txt ]
    then
        RETRYFILE="/etc/cron.hourly/lh_backup_retry.sh"
        echo "#!/bin/bash" > $RETRYFILE
        echo "#This file was autogenerated and will be removed by lh_system_backup_job" >> $RETRYFILE
        echo "MYTH_RUN_STATUS=1">> $RETRYFILE
        echo ". /etc/profile">> $RETRYFILE
        echo "lh_system_backup_job retry">> $RETRYFILE
        chmod 755 $RETRYFILE
    fi
}

function remove_link(){
    RETRYFILE="/etc/cron.hourly/lh_backup_retry.sh"
    if [ ! -f $BACKUPDIR/remote_backup_failed.txt ]
    then
        rm -f $RETRYFILE
    fi
}


#------------------------------------
lock_myth
if [ "x$1" = "x" ]
then
    backup
    #update_backup_status
    #only remove old backups if there was no problems
    if [ $backup_status -eq 0 ]
    then
        remove_old_backups
    fi
    remote_backup
    add_link
else
    #this is where we attempt to transfer again as part of the cronjob
    if [ -f $BACKUPDIR/remote_backup_failed.txt ]
    then
        mv -f $BACKUPDIR/remote_backup_failed.txt /tmp
        while read line
        do
            echo $line
            remote_transfer $line
        done < /tmp/remote_backup_failed.txt
        rm -f /tmp/remote_backup_failed.txt
    fi
    remove_link
fi
unlock_myth
echo $backup_status > /var/run/systembackup.rc
exit $backup_status
