#!/bin/bash

# Copyright (c) 2016, Kendrick Shaw, Jeffrey Gill, Hillel Chiel
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#  * Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.


DEFAULTNAME=$(hostname)-backup-$(date +'%Y%m%dT%H%M%S%z') # ISO-8601 timestamp

SQLUSER=root
SQLPASS=<MySQL password>
WIKIDB=wikidb
DJANGODB=djangodb

WWWDIR=/var/www
WIKIDIR=$WWWDIR/mediawiki
DJANGODIR=$WWWDIR/django


function usage {
    echo "Usage:"
    echo "  backup-wiki backup  [-q] [backup_filename]"
    echo "  backup-wiki restore [-q]  backup_filename"
    echo
    echo "Options:"
    echo "  -q  Quiet mode, print only errors"
    exit
}


# read in options
QUIET=false
while getopts ":q" opt; do
    case $opt in
        q)
            # the flag -q was set
            QUIET=true
            ;;
        \?)
            # an unrecognized flag was set
            echo "Invalid option: -$OPTARG" >&2
            usage
            ;;
    esac
done
shift $((OPTIND-1))


# read in backup_file argument
if [ -z "$2" ]; then
    # second argument not provided -- use default file name
    BACKUPNAME=$DEFAULTNAME
else
    BACKUPNAME=$(dirname $2)/$(basename $2 .tar.bz2)
fi


##### BACKUP MODE #####

if [ "backup" == "$1" ]; then

    if [ $QUIET = false ]; then
        echo "Starting backup to archive $BACKUPNAME.tar.bz2 ..."
    fi

    # create a temporary directory
    if [ $QUIET = false ]; then
        echo "Creating temporary directory ..."
    fi
    TEMPDIR=$(mktemp -d)

    # copy the MediaWiki, Django, and JSNeuroSim source code
    if [ $QUIET = false ]; then
        echo "Copying files ..."
    fi
    cp -R $WWWDIR $TEMPDIR

    # dump the wiki database in sql format
    if [ $QUIET = false ]; then
        echo "Exporting the wiki database in SQL format ..."
    fi
    mysqldump --user=$SQLUSER --password=$SQLPASS $WIKIDB --complete-insert --result-file $TEMPDIR/wikidb.sql 2>&1 | grep -v "\[Warning\] Using a password"

    # dump the django database in sql format
    if [ $QUIET = false ]; then
        echo "Exporting the Django database in SQL format ..."
    fi
    mysqldump --user=$SQLUSER --password=$SQLPASS $DJANGODB --complete-insert --result-file $TEMPDIR/djangodb.sql 2>&1 | grep -v "\[Warning\] Using a password"

    # dump the django database in json format (a more portable backup of the content)
    if [ $QUIET = false ]; then
        echo "Exporting the Django database in JSON format ..."
    fi
    python $DJANGODIR/manage.py dumpdata > $TEMPDIR/djangodb.json

    # compress everything into a single file
    if [ $QUIET = false ]; then
        echo "Compressing directory into an archive file ..."
    fi
    mkdir -p $(dirname $BACKUPNAME)
    tar -cjf $BACKUPNAME.tar.bz2 -C $TEMPDIR .
    chmod o= $BACKUPNAME.tar.bz2

    # delete the temporary directory
    if [ $QUIET = false ]; then
        echo "Deleting temporary directory ..."
    fi
    rm -rf $TEMPDIR

    if [ $QUIET = false ]; then
        echo "Done!"
        echo
        echo "NOTE: The backup you just created contains sensitive student information, quiz"
        echo "answers, and passwords. Keep this file in a safe place!"
        echo
    fi


##### RESTORE MODE #####

elif [ "restore" == "$1" ]; then

    if [ -z "$2" ]; then

        echo "Missing argument: backup_filename" >&2
        usage

    elif [ -e "$BACKUPNAME.tar.bz2" ]; then

        if [ "$(whoami)" != "root" ]; then

            echo "Aborting: superuser privileges needed" >&2
            usage

        else

            if [ $QUIET = false ]; then
                echo "Starting restoration from archive $BACKUPNAME.tar.bz2 ..."
            fi

            # extract the files
            if [ $QUIET = false ]; then
                echo "Unpacking archive ..."
            fi
            TEMPDIR=$(mktemp -d)
            tar -xjf $BACKUPNAME.tar.bz2 -C $TEMPDIR

            # stop the server
            if [ $QUIET = false ]; then
                echo "Stopping the web server ..."
            fi
            apache2ctl stop

            # copy the files, fixing permissions and owners
            if [ $QUIET = false ]; then
                echo "Copying files ..."
            fi
            rm -rf $WWWDIR
            cp -R $TEMPDIR/$(basename $WWWDIR) $WWWDIR
            chown -R www-data:www-data $WWWDIR
            chmod -R ug+rw $WWWDIR
            find $WWWDIR -type d -exec chmod g+s {} \;

            # restore the wiki database
            if [ $QUIET = false ]; then
                echo "Restoring the wiki database ..."
            fi
            echo "DROP DATABASE IF EXISTS $WIKIDB;" | mysql --user=$SQLUSER --password=$SQLPASS 2>&1 | grep -v "\[Warning\] Using a password"
            echo "CREATE DATABASE $WIKIDB;" | mysql --user=$SQLUSER --password=$SQLPASS 2>&1 | grep -v "\[Warning\] Using a password"
            mysql --user=$SQLUSER --password=$SQLPASS $WIKIDB < $TEMPDIR/wikidb.sql 2>&1 | grep -v "\[Warning\] Using a password"

            # restore the django database
            if [ $QUIET = false ]; then
                echo "Restoring the Django database ..."
            fi
            echo "DROP DATABASE IF EXISTS $DJANGODB;" | mysql --user=$SQLUSER --password=$SQLPASS 2>&1 | grep -v "\[Warning\] Using a password"
            echo "CREATE DATABASE $DJANGODB;" | mysql --user=$SQLUSER --password=$SQLPASS 2>&1 | grep -v "\[Warning\] Using a password"
            mysql --user=$SQLUSER --password=$SQLPASS $DJANGODB < $TEMPDIR/djangodb.sql 2>&1 | grep -v "\[Warning\] Using a password"

            # restart the server and clean-up
            if [ $QUIET = false ]; then
                echo "Restarting the web server ..."
            fi
            apache2ctl start
            rm -rf $TEMPDIR

            if [ $QUIET = false ]; then
                echo "Done!"
            fi

        fi

    else

        echo "Bad argument: file $BACKUPNAME not found" >&2
        usage

    fi


else
    usage
fi