#!/usr/local/bin/bash

# Copyright (c) 2015-2020 Oliver Mahmoudi
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted providing that the following conditions 
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. 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 AUTHOR ``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 AUTHOR 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.

# Place this script in the folder to which you copy your backups and run it
# to:
# 	a) check the files for errors via gzip --test and 
# 	b) generate their checksums.
# 
# Later, the generated report file can be diffed with the original report file 
# on the users hard drive.

# Variables:
WHO=$(whoami)
USER_REPORT_FILE=${WHO}_report
ETC_REPORT_FILE=etc_report

# Functions:
# create_report_file
# get_path_to_file
# get_filename
# delete_backup

create_report_file()
{
	local _contents
	
	if [ "$1" = "etc" ] ; then
		_contents=etc*.tar.gz
		: > ${ETC_REPORT_FILE}
	else
		_contents=*.tar.gz
		: > ${USER_REPORT_FILE}
	fi

	for i in ${_contents} ; do
		gzip --test ${i} > /dev/null 2>&1
		if [ $? -eq 0 ] ; then
			if [ "$1" = "etc" ] ; then
				sha256 ${i} >> ${ETC_REPORT_FILE}
			else
				sha256 ${i} >> ${USER_REPORT_FILE}
			fi
		else
			if [ "$1" = "etc" ] ; then
				echo "File: ${i} is corrupted." >> ${ETC_REPORT_FILE}
			else
				echo "File: ${i} is corrupted." >> ${USER_REPORT_FILE}
			fi
		fi
	done
}

get_path_to_file()
{
	local _awkvar _ptf

	# Get the left part of the last "/" aka path to file.
	_ptf=$(awk -v _awkvar=$1 'BEGIN { 
		string = "";
		n = split(_awkvar, a, "/");

		for(i = 2; i < n; i++) 
			string = string"/"a[i];

		string = string"/";
		print string;
		}')

	echo $_ptf
}

get_filename()
{
	local _awkvar _fn

	# Get the right part of the last "/" aka filename.
	_fn=$(awk -v _awkvar=$1 'BEGIN { 
		n = split(_awkvar, a, "/");
		print a[n];
		}')

	echo $_fn
}

delete_backup()
{
	local _bu _choice _file _ln _nobs _rf _rf_flag

	# Check for the existence of the backup that we seek to delete.
	_bu=$(realpath $1)
	if [ ! -f $_bu ]; then
		echo "The backup: $_bu doesn't exist."
		exit
	fi

	# Construct the report file and see if it exists in the target directory.
	# If not, continue but set _rf_flag to 1
	_rf_flag=0
	_rf=$(get_path_to_file $_bu)${USER_REPORT_FILE}
	if [ ! -f $_rf ]; then
		_rf=$(get_path_to_file $_bu)${ETC_REPORT_FILE}
		if [ ! -f $_rf ]; then
			echo "The reportfile doesn't exist."
			_rf_flag=1
		fi
	fi

	# Check if the entry in our reportfile is unique. If so, get the line number.
	if [ $_rf_flag -eq 0 ] ; then
		_file=$(get_filename $_bu)
		_nobs=$(cat $_rf | grep -c $_file)
		if [ $_nobs -eq 0 ]; then
			echo "No entry for: $_file in reportfile."
			_rf_flag=1
		elif [ $_nobs -eq 1 ]; then
			_ln=$(cat $_rf | grep -n $_file)
		else
			# Not probable but still...
			echo "Entry for: $_file in reportfile not unique."
			_rf_flag=1
		fi
	fi

	# Make sure and delete the backup. Otherwise abort.
	echo "This will delete your backup: $_bu"
	echo "Are you sure? [yes or no]: "
	read -t 30 _choice		# We got 30 seconds to make a choice

	case $_choice in
	[Yy][Ee][Ss] | [Yy] )
		if [ $_rf_flag -eq 0 ] ; then
			sed -i ${_ln%:*}d $_rf
		fi
		rm $_bu
		exit 0
		;;
	[Nn][Oo] | [Nn] )
		echo 'Aborted!'
		exit 1
		;;
	*)
		echo "Terminating."
		exit 1
		;;
	esac
}

usage()
{
	echo "usage:" 
	echo "bu_check_files [-u] [-d backup]"
	echo "bu_check_files etc"
}

### entry point

while getopts ":d:u" opt ; do
        case $opt in
                d)
                        delete_backup $OPTARG
                        ;;
                u)
                        usage
						exit 0
                        ;;
                \?)
                        echo "unkown flag: -$OPTARG."
                        usage
                        exit 1
                        ;;
				:)
						echo "The -$OPTARG flag needs an argument"
                        usage
						exit 1
						;;
        esac
done

shift $((OPTIND-1))

if [ "$1" = "etc" ] ; then
	create_report_file "etc"
else
	create_report_file
fi

echo 'Done!'
exit 0
