#!/bin/bash

# Debdle. Command-line utility to backup and restore installed deb packages.
# usage debdle [opt]

YLL='\033[0;33m'
LGR='\033[1;37m'
GRY='\033[1;30m'
GRN='\033[0;32m'
LGRN='\033[1;32m'
RED='\033[0;31m'
LRED='\033[1;31m'
CYN='\033[0;36m'
BLU='\033[1;36m'
NC='\033[0m'

if [[ -z ${@:1} || $1 == --help ]]; then
	echo "Debdle. Command line utility to backup and restore installed deb packages.

usage : debdle [opt]

opt.
-b    : backup packages.
-c    : fixing unconfigured packages and check for missing dependencies.
-exs  : exclude Jailbreak system package when backup all. (-b)
-res  : restore packages.
-r    : remove packages.
-q    : quiet mode.

for -b -res -r options can be executed either one by one, batch, or all.

all your tweaks will be saved into /var/mobile/Documents/Backdeb"

exit 0
fi

err()
{
if [ ! $? -eq 0 ]; then
echo -e "${LGR}debdle: ${LRED}error:${NC} Bad type, Try again"
exit
fi
}
btch()
{
er=($(echo "$sel"))
cn=$(comm -13 $cut $tweaks | wc -l)
x=$(expr $cn + 3)
y=$(expr $cn + 2)
if [ $sel -gt $x 2>/dev/null ]; then
echo -e "${LGR}debdle: ${LRED}error:${NC} Invalid, try again."
sel='';
elif [[ $sel == $x ]]; then
rm $tweaks
exit
elif [[ $sel == $y ]]; then
echo -e "${LGR}debdle: ${LRED}error:${NC} Invalid, try again."
sel='';
elif [[ $er =~ ^[0-9]+$ ]]; then
:
else
    echo -e "${LGR}debdle: ${LRED}error:${NC} Bad type, try again."
    sel='';
fi
}

if [ $1 == -b ]; then
:
elif [ $1 == -c ]; then
:
elif [ $1 == -r ]; then
:
elif [ $1 == -res ]; then
:
elif [ $1 == --help ]; then
:
else
echo -e "${LGR}debdle: ${LRED}error:${NC} Invalid Options, try again"
exit
fi

bckup=/var/mobile/Documents/Backdeb
cut=/Library/Debdle/coretweaks.txt
tweaks=/Library/Debdle/tweaks.txt
dpkg --get-selections | grep install | grep -v gsc. | sed 's/\s.*$//' > $tweaks && chmod +x $tweaks

if [ $1 == -c ]; then
	echo -e "${LGR}debdle: ${GRN}fix:${NC} Setting up leftover..."
	dpkg --configure -a > /dev/null 2>&1
	sleep 3;
echo -e "${LGR}debdle: ${GRN}fix:${NC} Checking broken packages..."
	sleep 3;
	if [ -z "$(ls -A $bckup 2>/dev/null)" ]; then
echo -e "${LGR}debdle: ${LRED}failed:${NC} file not found, backup your tweak first."
		sleep 2;
	else
		cl=$(ls $bckup | sed '/sources/d' | sed 's/.\w*$//' | tr '\n' ' ')
		dpkg -C $cl
	fi
echo -e "${LGR}debdle: ${GRN}fix:${NC} Checking dependencies..."
dpkg --configure -a; 2>/dev/null
path=/var/mobile/Documents/Backdeb/sources.txt
src=/var/mobile/Library/Caches/com.saurik.Cydia/sources.list
srcc=/etc/apt/sources.list.d/sileo.sources
	if [ -f "$src" ]; then
		cat $path 2>/dev/null | sed 's/^/deb /' | sed 's/$/\ .\//' >> $src
echo "Updating Sources..."
		apt-get update > /dev/null 2>&1;
	elif [ -f "$srcc" ]; then
		tmpl=/var/tmp/src.txt
		nm()
		{
echo "Types: deb
URIs: $line
Suites: ./
Components:

"
		}
		rm $tmpl 2>/dev/null
		touch $tmpl
		cat $path 2>/dev/null | sed '/zodttd\|memoose\|thebigboss\|chariz\|modmyi\|dynastic\|bingner/d' | while IFS= read line; do 
		nm | grep -vxFf $srcc | cut -d ' ' -f2 >> $tmpl
		done
		if [ -s $tmpl ] ; then
			num=$(wc -l < $tmpl)
			while true; do
read -p "You have $num repo sources in your backup, do you want to add it?[Y/N] " yn
				case $yn in
					[Yy]* )
echo "Adding Sources..."
						cat $tmpl | while IFS= read line; do
						nm >> $srcc
						done
echo "Updating Sources..."
						apt-get update > /dev/null 2>&1;
						break;;
					[Nn]* ) rm $tmpl
						break;;
*) echo "Please answer y/n.";;
				esac
			done
		else
			rm $tmpl > /dev/null 2>&1;
		fi
	fi
	apt-get --assume-no -f install > /var/mobile/er.txt 2>&1;
	if [ ! $? -eq 0 ]; then
		pec=$(uname -p)
		if [ $pec == arm ]; then
			rm /var/mobile/er.txt
		else
		log=/var/mobile/ers.txt
			cat /var/mobile/er.txt | grep 'newly' | awk '{$NF=""}1' |  tr ',' '\n' | sed 's/and/\n/g' > /var/mobile/ers.txt
			new=$(cat $log | grep 'newly' | tr -dc '0-9')
			up=$(cat $log | grep 'not' | tr -dc '0-9')
			nup=$(echo "$up not upgraded tweaks.")
echo -e "${LGR}debdle:${NC} found $new unconfigured dependencies $nup"
			sleep 3;
		fi
		rm $log
	fi
	rm /var/mobile/er.txt
echo -e  "${LGR}debdle: ${GRN}fix:${NC} Clean up configuration..."
	apt-get autoremove -y > /dev/null 2>&1;
	apt autoclean -y > /dev/null 2>&1;
	apt-get --allow-unauthenticated upgrade -y 2>/dev/null;
apt-get --allow-unauthenticated --fix-broken install -y
	apt-get --allow-downgrades --allow-unauthenticated --fix-broken install -y > /dev/null 2>&1;
	apt-get -f --allow-downgrades --allow-unauthenticated install -y > /dev/null 2>&1;
	apt-get --allow-downgrades --allow-unauthenticated full-upgrade -y > /dev/null 2>&1;
echo -e  "${LGR}debdle: ${GRN}fix:${NC} Running uicache..."
sleep 1.6;
pec=$(uname -p)
if [ $pec == arm ]; then
uicache
else
ls -d /Applications/*/ | sed '/Feedback\|Safari\|Phone/d' | while IFS= read line; do
ui()
{
echo "$line" && uicache --path "$line" 2>/dev/null;
}
ui
uipid=$!
wait $uipid
done
fi
echo -e "${LGR}debdle: ${LGRN}Fixed!${NC}"
echo -e "${LGR}debdle:${NC} RESPRING REQUIRED!"
	while true; do
	read -p "Do you want to respring your device?[Y/N]: " yn
		case $yn in
[Yy]* ) echo "your phone will
respring in 3..."
  			sleep 1;
  			echo "will respring in 2..."
  			sleep 1;
  			echo "will respring in 1..."
  			sleep 1;
  			killall -9 backboardd;
break;;
[Nn]* ) break;;
* ) echo "please type y/n";;
		esac
	done
exit 0
fi

if [ $1 == -r ]; then
B=$(echo -e ${YLL}BATCH REMOVE${NC})
R=$(echo -e "${YLL}REMOVE ALL${NC}")
Q=$(echo -e ${RED}QUIT${NC})
flx()
{
rm -r /Applications/Flex.app 2>/dev/null;
}
uic()
{
srcc=/etc/apt/sources.list.d/sileo.sources
if [ -f $srcc ]; then
				uicache -a
else
uicache
fi
}

	if [ ! -f "/Library/Debdle/coretweaks.txt" ]; then
		echo "Lists not found, please
			re-install Debdle"
			exit
	else
  cut=/Library/Debdle/coretweaks.txt
  tweaks=/Library/Debdle/tweaks.txt
  dpkg --get-selections | grep install | grep -v gsc. | sed 's/\s.*$//' > $tweaks && chmod +x $tweaks

	options=($(comm -13 $cut $tweaks))
	PS3="Please select package to remove: "

		select opt in "${options[@]}" "$B" "$R" "$Q"; do

			if (( REPLY == 3 + ${#options[@]} )) 2>/dev/null ; then
				rm $tweaks 
				exit

			elif (( REPLY == 1 + ${#options[@]} )) 2>/dev/null ; then
#collecting number for batch remove.
			while [[ $sel == '' ]]; do
			read -p "Choose number by spaces: " sel
			btch
			done
			selected=$(comm -13 $cut $tweaks | sed -n "$( echo "$sel" | sed 's/[0-9]\+/&p;/g')" 2>/dev/null)
echo -e "${LGR}debdle:${NC} Removing..."
				if [[ $1 == -q || $2 == -q ]]; then
					dpkg -r --force-all $selected > /dev/null 2>&1;
					err
				else
					dpkg -r --force-all $selected 2>/dev/null
					err
				fi
				if [[ $selected == *flex3beta* ]]; then
				flx
				fi
echo -e "${LGR}debdle:${NC} Clean up..."
				dpkg --purge $selected > /dev/null 2>&1
				apt-get autoremove -y > /dev/null 2>&1;
echo "Running uicache..."
uic
				rm $tweaks
echo -e "${LGR}debdle:${NC} Done!, you might want to run -c to fix dependencies"
				exit 0

			elif (( REPLY == 2 + ${#options[@]} )) 2>/dev/null ; then
#getting list
			all=$(comm -13 $cut $tweaks | sed '/terminal\|com.moose.debdle\|com.moose.rebd/d' | tr '\n' ' ')
#execute and clean up
				if [[ $1 == -q || $2 == -q ]]; then
					dpkg -r --force-all $all > /dev/null 2>&1;
				else
					dpkg -r --force-all $all 2>/dev/null
				fi
				if [[ $all == *flex3beta* ]]; then
				flx
				fi
echo -e  "${LGR}debdle:${NC} Clean up..."
				dpkg --purge $all > /dev/null 2>&1
				apt-get autoremove -y > /dev/null 2>&1;
				apt-get --allow-unauthenticated --fix-broken install -y > /dev/null 2>&1;
echo -e "${LGR}debdle:${NC} please wait, RESPRING REQUIRED..."
echo "Running uicache..."
uic
				rm $tweaks
echo "your phone
will respring in 3..."
  			sleep 1;
  			echo "will respring in 2..."
  			sleep 1;
  			echo "will respring in 1..."
  			sleep 1;
         killall -9 backboardd
exit
  		elif (( REPLY > 0 && REPLY <= ${#options[@]} )) 2>/dev/null; then
echo -e "${LGR}debdle:${NC} Uninstalling..."
				if [[ $1 == -q || $2 == -q ]]; then
					dpkg -r --force-all $opt > /dev/null 2>&1;
					err
				else
					dpkg -r --force-all $opt 2>/dev/null
					err
				fi
				if [[ $opt == *flex3beta* ]]; then
				flx
				fi
echo -e "${LGR}debdle:${NC} Clean up..."
				dpkg --purge "$opt" > /dev/null 2>&1
				apt-get autoremove -y > /dev/null 2>&1;
echo "Running uicache..."
uic
echo -e "${LGR}debdle:${NC} Done!"
				rm $tweaks
				exit 0
  		else
echo -e "${LGR}debdle: ${LRED}error:${NC} Bad type, Try again"
			fi
		done
	fi
exit 0
fi

if [ $1 == -res ]; then
while true; do
W=$(echo -e "${LGR}WARNING!!
${LRED}TURN ON YOUR TWEAK INJECTION FIRST.${NC}")
read -p " $W [Yes,i did/N]: " yn
	case $yn in
		[Yy]* ) break;;
		[Nn]* ) exit;;
		*) echo "please answer Y/N";
	esac
done

if [[ -z "$(ls -A $bckup 2>/dev/null)" || ! -d $bckup ]]; then
echo -e "${LGR}debdle: ${YLL}warning:${NC} you haven't backup any tweaks yet."
exit 7
fi
echo -e "${LGR}debdle:${NC} Collecting files, please wait..."
for file in $bckup/*.deb; do
nm=$(dpkg-deb -f $file Package 2>/dev/null)
	mv "$file" "$bckup/$nm.deb" > /dev/null 2>&1;
done

B=$(echo -e ${YLL}BATCH RESTORE${NC})
R=$(echo -e "${YLL}RESTORE ALL${NC}")
Q=$(echo -e ${RED}QUIT${NC})
options=($(ls $bckup | sed '/sources\|terminal\|newterm/d'))

PS3="Please select package to restore: "
	select opt in "${options[@]}" "$B" "$R" "$Q"; do

		if (( REPLY == 3 + ${#options[@]} )) 2>/dev/null; then
			exit
#batch restore process
		elif (( REPLY == 1 + ${#options[@]} )) 2>/dev/null; then
		while [[ $sel == '' ]]; do
			read -p "Choose number: " sel
			er=($(echo "$sel"))
			cn=$(ls $bckup | sed '/sources\|terminal\|newterm/d' | wc -l)
			x=$(expr $cn + 3)
			y=$(expr $cn + 2)
			if [[ $sel == $x ]]; then
				exit 0
			elif [[ $sel == $y ]]; then
echo -e "${LGR}debdle: ${LRED}error:${NC} Invalid, try again."
				sel='';
			elif [[ $er =~ ^[0-9]+$ ]]; then
				break;
			else
echo -e "${LGR}debdle: ${LRED}error:${NC} Bad type, try again."
				sel='';
			fi
		done
			selected=$(ls $bckup | sed '/sources\|terminal\|newterm/d' | sed -n "$( echo "$sel" | sed 's/[0-9]\+/&p;/g')")
#restoring selected tweaks
			echo -e "${LGR}debdle:${NC} Restore..."
			cd $bckup
			if [[ $1 == -q || $2 == -q ]]; then
				dpkg -i --force-depends $selected > /dev/null 2>&1;
				err
			else
				dpkg -i --force-depends $selected 2>/dev/null
				err
			fi
				echo -e "${LGR}debdle:${NC} Done!, you might want to run -c to fix dependencies."
				exit 0
		elif (( REPLY == 2 + ${#options[@]} )) 2>/dev/null; then
		while true; do
			read -p "If you experience force close or auto respring during packages configuration, you may need to run -c after.
Do you wish to continue?[Y/N]: " yn
			case $yn in
        [Yy]* ) break;;

        [Nn]* ) rm $tweaks; exit;;

        * ) echo "Please answer yes or no.";;
      esac
    done

echo -e "${LGR}RESTORING ALL TWEAK...${NC}"
sleep 1
#install packages that used alot as dependencies first, to prevent errors during the installation process.
frs=$(ls $bckup | grep 'appsyncunified\|reprovision' | tr '\n' ' ')
cd $bckup
mkdir frs && cp $frs frs 2> /dev/null
if [[ $1 == -q || $2 == -q ]]; then
ins()
{
for file in $bckup/frs/*.deb; do
	dpkg -i --force-depends $file > /dev/null 2>&1;
done
}
ins &
inspid=$!
wait $inspid

else
ins()
{
for file in $bckup/frs/*.deb; do
	dpkg -i --force-depends $file 2> /dev/null;
done
}
ins &
inspid=$!
wait $inspid
fi
rm -r $bckup/frs
#prepare install
lst=$(ls $bckup | sed '/sources\|terminal\|newterm/d')
echo "$lst" | while IRS= read -r line; do
if [ $line == cydia.com.ipc.crackerxi.deb ]; then
:
elif [ $line == net.angelxwind.appsyncunified.deb ]; then
:
elif [ $line == com.matchstic.reprovision.deb ]; then
:
else
#install all!!
	if [[ $1 == -q || $2 == -q ]]; then
	ins()
{
		dpkg -i --force-depends $bckup/$line > /dev/null 2>&1;
}
	ins &
	inspid=$!
	wait $inspid
	else
	ins()
{
		dpkg -i --force-depends $bckup/$line 2> /dev/null;
}
	ins &
	inspid=$!
	wait $inspid
	fi
fi
done

end=$(ls $bckup | grep 'crackerxi')
if [[ -f $bckup/$end ]]; then
	if [[ $1 == -q || $2 == -q ]]; then
	ins()
{
		dpkg -i --force-depends $bckup/$end > /dev/null 2>&1;
}
	ins &
	inspid=$!
	wait $inspid
	else
	ins()
{
		dpkg -i --force-depends $bckup/$end 2> /dev/null;
}
	ins &
	inspid=$!
	wait $inspid
	fi
sleep 2;
fi

echo -e "${LGR}debdle:${NC} Done!, Please run -c to complete the proccess."
        exit 0

  		elif (( REPLY > 0 && REPLY <= ${#options[@]} )) 2>/dev/null; then
  			echo -e "${LGR}Restoring...${NC}"
  			if [[ $1 == -q || $2 == -q ]]; then
  			ins()
{
					dpkg -i --force-depends $bckup/$opt > /dev/null/ 2>&1;
					err
}
				ins &
				inspid=$!
				wait $inspid
				else
				ins()
{ 
					dpkg -i --force-depends $bckup/$opt 2>/dev/null;
					err
}
				ins &
				inspid=$!
				wait $inspid
				fi
echo -e "${LGR}debdle:${NC} Clean up..."
apt-get --allow-unauthenticated --fix-broken install -y
echo "Running uicache..."
srcc=/etc/apt/sources.list.d/sileo.sources
if [ -f $srcc ]; then
	uicache -a
else
	uicache
fi
echo -e "${LGR}debdle:${NC} Done!"
  			exit 0
  		else
  			echo -e "${LGR}debdle: ${LRED}error:${NC} Bad Type, Try again"
  		fi
  	done
  fi

if [ $1 == -b ]; then
#Prepare and getting list
mkdir $bckup > /dev/null 2>&1;
cd $bckup

	if [ ! -f "/Library/Debdle/coretweaks.txt" ]; then
		echo "Lists not found, please re-install Debdle"
		exit
	else
		cut=/Library/Debdle/coretweaks.txt
		dpkg --get-selections | grep install | grep -v gsc. | sed 's/\s.*$//' > $tweaks && chmod +x $tweaks
B=$(echo -e ${YLL}BATCH BACKUP${NC})
R=$(echo -e "${YLL}BACKUP ALL${NC}")
Q=$(echo -e ${RED}QUIT${NC})

options=($(comm -13 $cut $tweaks | sed '/terminal\|newterm/d'))
PS3="Please select num of package to backup: "
	select opt in "${options[@]}" "$B" "$R" "$Q"; do

		if (( REPLY == 3 + ${#options[@]} )) 2>/dev/null; then
			rm $tweaks
			exit
			
		elif (( REPLY == 1 + ${#options[@]} )) 2>/dev/null; then
			while [[ $sel == '' ]]; do
			read -p "Choose number by spaces: " sel
btch
done

      selected=$(comm -13 $cut $tweaks | sed '/terminal\|newterm/d' | sed -n "$( echo "$sel" | sed 's/[0-9]\+/&p;/g')")
echo -e "${LGR}Backing up...${NC}"

			if [[ $2 == -q || $1 == -q ]]; then
			bck()
{
				rebd -q $selected $bckup
}
			bck &
			bckpid=$!
			wait $bckpid
			else
			bck()
{
				rebd $selected $bckup
}
			bck &
			bckpid=$!
			wait $bckpid
			fi

if [ -d /Applications/Sileo.app ]; then
sil=/etc/apt/sources.list.d/sileo.sources
cat $sil | grep http | cut -d ' ' -f2 > $bckup/sources.txt
else
			cat /var/mobile/Library/Caches/com.saurik.Cydia/sources.list 2>/dev/null | cut -f 2- -d ' ' | grep -o '^\S*' > $bckup/sources.txt 2>/dev/null
fi
echo -e "${LGR}debdle:${NC} Done!"
			rm $tweaks
			exit 0

    elif (( REPLY == 2 + ${#options[@]} )) 2>/dev/null; then
		all=$(comm -13 $cut $tweaks | sed '/terminal\|newterm/d' | tr '\n' ' ')
echo -e "${LGR}Backing up...${NC}"
			while true; do
			case "$2" in
				-q) if [[ $3 == -exs ]]; then
bck()
{
				rebd -q -exs $all $bckup
}
			bck &
			bckpid=$!
			wait $bckpid
						else
bck()
{
				rebd -q $all $bckup
}
			bck &
			bckpid=$!
			wait $bckpid
						fi
				;;
				-exs) if [[ $3 == -q ]]; then
bck()
{
				rebd -q -exs $all $bckup
}
			bck &
			bckpid=$!
			wait $bckpid
							else
bck()
{
				rebd -exs $all $bckup
}
			bck &
			bckpid=$!
			wait $bckpid
							fi
					;;
					*) bck()
{
				rebd $all $bckup
}
			bck &
			bckpid=$!
			wait $bckpid
					;;
			esac
			break;
			done

if [ -d /Applications/Sileo.app ]; then
sil=/etc/apt/sources.list.d/sileo.sources
cat $sil | grep http | cut -d ' ' -f2 > $bckup/sources.txt
else
			cat /var/mobile/Library/Caches/com.saurik.Cydia/sources.list 2>/dev/null | cut -f 2- -d ' ' | grep -o '^\S*' > $bckup/sources.txt 2>/dev/null
fi
echo -e "${LGR}debdle:${NC} Done!"
			rm $tweaks
			exit 0

		elif (( REPLY > 0 && REPLY <= ${#options[@]} )) 2>/dev/null; then
			echo -e "${LGR}Backing up...${NC}"
			
			if [[ $2 == -q || $1 == -q ]]; then
			bck()
{
				rebd -q $opt $bckup
}
			bck &
			bckpid=$!
			wait $bckpid
			else
			bck()
{
				rebd $opt $bckup
}
			bck &
			bckpid=$!
			wait $bckpid
			fi

if [ -d /Applications/Sileo.app ]; then
sil=/etc/apt/sources.list.d/sileo.sources
cat $sil | grep http | cut -d ' ' -f2 > $bckup/sources.txt
else
			cat /var/mobile/Library/Caches/com.saurik.Cydia/sources.list 2>/dev/null | cut -f 2- -d ' ' | grep -o '^\S*' > $bckup/sources.txt 2>/dev/null
fi
echo -e "${LGR}debdle:${NC} Done!"
			rm $tweaks
			exit 0
  	else
  		echo -e "${LGR}debdle: ${LRED}error:${NC} Bad Type, Try again"
  		rm $tweaks
  		exit
		fi
	break;
	done
	fi
fi
exit 0

#FINALLY DONE

#Moose <gathering011@gmail.com>