#!/bin/bash
CURRENT_PATH=`pwd`

function compare_snapshots(){
	cd /tmp/diffshot

	diff snapshot1 snapshot2 |grep ">"|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|cut -c 4- >created
	diff snapshot1 snapshot2 |grep "<"|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|awk '!($2="")'|cut -c 4- >deleted

	cat deleted created |sort|uniq -d > modified-files						# Files deleted and created again are modified files
	cat created modified-files|sort|uniq -u |sed 's/^/>/' > new-files		# ">" for created files, "<" for deleted files and nothing for modified files          
	cat deleted modified-files|sort|uniq -u |sed 's/^/</' > deleted-files

	cat new-files deleted-files modified-files > comparation
	cat comparation

}



case "$1" in
	"")
echo "
Usage:

diffshot /path/to/scan [--exclude=txtfile]

Where «/path/to/scan» is the path to be scanned and «txtfile» is a text file with paths to be ignored, by default it will be ~/.config/diffshot/excluded and will ignore /proc, /sys, /dev, /run folders.  

This will create a text file called snapshot-[date] with a list of files in the /path/to/scan without excluded files or directories.
Then, you can add, remove and modify files in your system...and when you're done run one of this options:

diffshot compare [snapshot]
      to display output on the screen. No changes the filesystem.
      Paths started with "\>" means new files added.
      Paths started with "\<" means files deleted.
      Paths started with any symbol means files modifed.

diffshot createtgz [snapshot]
      to create a [snapshot].tgz with files added or modified.

diffshot createrun [snapshot]
      to create a [snapshot].run, a tgz autoextractable.

diffshot createupdate [snapshot]
      to create a [snapshot].run autoextractable but it will apply
      all changes done, that is, it will delete files too if it
      will be deleted before. It is used for update porpuses.

"
exit 0

;;
	"createdeb")
		echo "Crear un deb con los archivos modificados o creados."
;;
	"createtgz") # CREATE A COMPRESED TGZ WITH ALL FILES CREATED OR MODIFIED
		rm -r /tmp/diffshot/files/ 2>/dev/null
		if [ -e "${CURRENT_PATH}"/diffshot.tar.gz ];then
			echo "A diffshot.tar.gz file exists, you have to rename or remove it before to continue."
			exit 0
		fi
	
		if [ -e /tmp/diffshot/created ];then
			while [ ${answer:-void} == "void" ]; do
  			  read -p "A previus comparation exists, do you want to use it or do you want to scan files again?
	1) I want to use it.
	2) Scan again all files in the folder.
" answer
				echo -n ""
    			case "$answer" in
        			"1" ) 
						# We use a previous comparation"
						mkdir /tmp/diffshot/files
		
						exec < "/tmp/diffshot/created"
						while read line
						do
			
							cp -a --parents "$line" /tmp/diffshot/files/
			

						done
						
						
						cd /tmp/diffshot/files; tar -czvf "${CURRENT_PATH}/diffshot.tar.gz" *
						echo -e "\x1B[01;92m diffshot created: diffshot.tar.gz \x1B[0m" 1>&2

				;;
        			"2" ) 
						# We scan again all files
						diffshot compare "$2"
						mkdir /tmp/diffshot/files
		
						exec < "/tmp/diffshot/created"
						while read line
						do
			
							cp -a --parents "$line" /tmp/diffshot/files/
			

						done

						cd /tmp/diffshot/files; tar -czvf "${CURRENT_PATH}/diffshot.tar.gz" *
						echo -e "\x1B[01;92m diffshot created: diffshot.tar.gz \x1B[0m" 1>&2

				;;
				
        			* ) 
						echo ""
						echo "Please answer 1 or 2."
						unset answer
				;;
    			esac
			done

		else
		# Not exits previus snapshot created
		diffshot compare "$2"
		mkdir /tmp/diffshot/files
		exec < "/tmp/diffshot/created"
		while read line
			do
				cp -a --parents "$line" /tmp/diffshot/files/
			done

		cd /tmp/diffshot/files; tar -czvf "${CURRENT_PATH}/diffshot.tar.gz" *
		echo -e "\x1B[01;92m diffshot created: diffshot.tar.gz \x1B[0m" 1>&2
			

		fi

;;
	"createrun") # CREATE AN AUTO-EXTRACTABLE FILE

		rm /tmp/diffshot/autoextrae.run 2>/dev/null

		diffshot createtgz "$2"
		
		cat <<'EOF' >> extrae
#!/bin/bash
echo "Extract"
# We search for the line where finish this script and start the tgz

SALTA=`awk '/^__TGZ__/ { print NR + 1; exit 0; }' $0`

#ARCHIVO=`pwd`/$0
ARCHIVO=$0

# We join everything
gksudo "sh -c '(tail -n +$SALTA $ARCHIVO|tar xzvf - -C / )|zenity --progress --auto-close'"

# Here whatever you want to do AFTER auto-extraction
zenity --info --text "Finished!"
echo "Sacabó"
exit 0

# Warning: absolutely not write anything under this line.
__TGZ__
EOF

		
		cat extrae diffshot.tar.gz > diffshot.run
		chmod +x diffshot.run
		# rm diffshot.tar.gz 
		rm extrae

		
;;
	"createupdate") # CREATE AN AUTO-EXTRACTABLE FILE AND IT WILL REMOVE FILES REMOVED TOO FOR UPDATE PURPOSES

		rm extrae 2>/dev/null

		diffshot createtgz "$2"

		#Calculate Mb will be deleted
		#exec < /tmp/diffshot/deleted-files-clean
		#RESULTADO=0
		#while read line
		#do
    	#	SIZE=`cat snapshot1|grep "$line"|tail -n1|awk '{print $5}'`
    	#	echo $line': '$SIZE
    	#	RESULTADO=`echo $SIZE+$RESULTADO|bc`
		#done
		#MB_DELETED=`echo "scale=2; $RESULTADO/1024/1024"|bc`

		cat /tmp/diffshot/deleted-files| cut -c 2- >/tmp/diffshot/deleted-files-clean
		awk '$1="rm "$1' /tmp/diffshot/deleted-files-clean >/tmp/diffshot/rm-deleted

		cat <<'EOF' >> extrae
#!/bin/bash
echo "Extract"
# We search for the line where finish this script and start the tgz

SALTA=`awk '/^__TGZ__/ { print NR + 1; exit 0; }' $0`

#ARCHIVO=`pwd`/$0
ARCHIVO=$0

# We join everything
gksudo "sh -c '(tail -n +$SALTA $ARCHIVO|tar xzvf - -C / )|zenity --progress --auto-close'"

# Here whatever you want to do AFTER auto-extraction

EOF
cat extrae /tmp/diffshot/rm-deleted >extraetmp;mv extraetmp extrae

cat <<'EOF' >> extrae
zenity --info --text "Finished!"
echo "Sacabó"
exit 0

# Warning: absolutely not write anything under this line.
__TGZ__
EOF

		
		cat extrae diffshot.tar.gz > diffshot.run
		chmod +x diffshot.run

		# rm diffshot.tar.gz 
		#rm extrae

		




;;
	"compare")		# SHOW/OUTPUT CHANGES IN FILES

		rm -r /tmp/diffshot 2>/dev/null
		mkdir /tmp/diffshot 2>/dev/null

		if [ "$2" = "" ];then 
				echo "It is necessary an old snapshot file to compare with the current directory." 1>&2
				exit 0
		else
			if [ -f "$2" ];then
				
				# Create a current diffshot and compare with given as parameter
				OLD_SNAPSHOT="$2"
				
				PATH_SHOT=`cat "$2" |tail -n3|grep "#path:"|cut -d ":" -f2`
				NOTPATH=`cat "$2" |tail -n3|grep "#exclude:"|cut -d ":" -f2`
				OLD_DATE=`cat "$2" |tail -n3|grep "#date:"|cut -d ":" -f2`
				
				if [ -d "$PATH_SHOT" ];then
					echo "Path to be scanned: ${PATH_SHOT}" 1>&2
				else
					echo "Incorrect path." 1>&2
					exit 0
				fi
				# Showing the diff time between the old snapshot and the current date.
				DATE=$(date +"%d_%m_%Y_%s")
				OLD_DATEs=`echo $OLD_DATE|cut -d"_" -f4`
				DATEs=`echo $DATE|cut -d"_" -f4`
				DIFF_DATE=$(($DATEs-$OLD_DATEs))
					DAYS=$(($DIFF_DATE /60 /60 /24))
					HOURS=`echo "$DIFF_DATE /60 /60 % 24"|bc`
					MINUTES=`echo "$DIFF_DATE /60 %60"|bc`
					SECONDS=`echo "$DIFF_DATE %60"|bc`
				echo "Showing changes in  $DAYS days, $HOURS hours, $MINUTES minutes and $SECONDS seconds elapsed." 1>&2			

				a='find '"${PATH_SHOT}"' -type f '"${NOTPATH}"'-exec ls -l {} \; > snapshot-'${DATE}
				echo ""
				echo "${a}" 1>&2
				eval "${a}"

				echo "#path:""${PATH_SHOT}" >>snapshot-"${DATE}"
				echo "#exclude:""${NOTPATH}" >>snapshot-"${DATE}"
				echo "#date:"${DATE} >>snapshot-"${DATE}"
	
				cat `echo ${OLD_SNAPSHOT}` |head -n -3 > /tmp/diffshot/snapshot1
				cat `echo snapshot-${DATE}` |head -n -3 > /tmp/diffshot/snapshot2
				
				
				compare_snapshots



			else
				echo "The file doesn't exist."
			fi 
		fi
 
		
		
;;
	*)		# CREATE NEW SNAPSHOT WITH THE GIVEN PATH

		rm -r /tmp/diffshot 2>/dev/null
		mkdir /tmp/diffshot 2>/dev/null

		if [ -d "$1" ];then
			PATH_SHOT="$1"
			echo "Path to be scanned: ${PATH_SHOT}"
		else
			echo "Incorrect path."
			exit 0
		fi

		if [ "$2" = "" ];then				# If it hasn't been given exclude parameter
			if [ -e "$HOME/.config/diffshot/excluded" ];then 
				EXCLUDE="$HOME/.config/diffshot/excluded"
				echo "Paths to be excluded in: ${EXCLUDE}"
				cat `echo ${EXCLUDE}`
			else
				mkdir ~/.config/diffshot/ 2>/dev/null
				echo "/dev/*" > ~/.config/diffshot/excluded
				echo "/run/*" >> ~/.config/diffshot/excluded
				echo "/sys/*" >> ~/.config/diffshot/excluded
				echo "/tmp/*" >> ~/.config/diffshot/excluded
				echo "/proc/*">> ~/.config/diffshot/excluded
				EXCLUDE="$HOME/.config/diffshot/excluded"
				echo "Paths to be excluded in: ${EXCLUDE}"
				cat `echo ${EXCLUDE}`
			fi
		else								# If exclude file has been given
			EXCLUDE=`echo "$2"|cut -d"=" -f2`
			if [ -e "$EXCLUDE" ];then
				echo "Paths to be ignored in: ${EXCLUDE}"
				cat `echo "${EXCLUDE}"`
			else
				echo "Icorrect excluded file."
				exit 0
			fi
		
		fi

		exec < "${EXCLUDE}"
		while read line
		do
			NOTPATH=`echo "-not -path \"${line}\" ${NOTPATH}"`

		done

#ejemplo de find con exclusión
#find "/opt/" -type f -not -path "*/opt/adapro/*" -not -path "*Impro*" -exec ls -l {} \; >/tmp/snap1

		#echo $NOTPATH
		DATE=$(date +"%d_%m_%Y_%s")

		a='find '"${PATH_SHOT}"' -type f '"${NOTPATH}"'-exec ls -l {} \; >snapshot-'${DATE}
		echo "${a}"
		eval "${a}"

		echo "#path:""${PATH_SHOT}" >> snapshot-"${DATE}"
		echo "#exclude:""${NOTPATH}" >> snapshot-"${DATE}"
		echo "#date:"${DATE} >> snapshot-"${DATE}"
		echo ""
		
		echo -e "\x1B[01;92m Snapshot created: snapshot-${DATE} \x1B[0m" 1>&2

;;

esac

exit 0

