#!/bin/bash
# This script was auto generated using the code-cleanup package http://forumubuntusoftware.info/viewtopic.php?f=23&t=9480
# Do a search and replace for ultimateedition.info followed by a search and replace ue-tweaker with the name of your program & delete this line.

# ==============================================================================
# title			:ue-tweaker
# description	:Ultimate Edition Tweaker
# author		:theemahn <theemahn@ultimateedition.info>
# date			:03/09/2021
# version		:1.0
# usage			:ue-tweaker --help
# manual		:man ue-tweaker
# notes			:See change-log below for further information.
# ==============================================================================
# Change-log: 1.0: unreleased
# ==============================================================================

# Modify the below information to correlate with the software you are designing.
APPNAME="Ultimate Edition Tweaker"
PROGNAME="ue-tweaker"
PROGRAMMER="theemahn"
BUILDDATE="03/15/2024"
VERSION="2.1.0"
DOMAIN="ultimateedition.info"
WEBSITE="http://${DOMAIN}/"
EMAIL="<${PROGRAMMER}@${DOMAIN}>"

if [[ -f "ultimate-common" ]]; then
	source ultimate-common
elif [[ -f "/usr/share/ultimate_edition/ultimate-common" ]]; then
	source /usr/share/ultimate_edition/ultimate-common
else
	echo "No Ultimate Edition common source. Please install ultimate-edition-common."
	exit 1;
fi

# Logging output - Currently un-implemented
# exec 1> /var/log/ue-tweaker.log
# exec 1>> /var/log/ue-tweaker.log 2>&1
# Multiple log files?
declare -a LOG_FILE=( "/var/log/ue-tweaker.log" );
# Single Log
# LOG_FILE="/var/log/ue-tweaker.log"
# exec 1 | tee ${LOG_FILE}
# exec 2 | tee ${LOG_FILE}

BootTime () {
	Center "Security"
	shopt -s nullglob
	declare -a BOOTTIME=();
	BOOTTIME=$(systemd-analyze security) & Spinner "Analyzing Security."
	BOOTTIME=();
	OIFS=$IFS
	IFS=$'\n'
	BOOTTIME=$(systemd-analyze) & Spinner "Analyzing Boottime."
	BOOTTIME=($BOOTTIME)
	IFS=$OIFS
	Center "Boot Time"
	for EACH in "${BOOTTIME[@]}"
	do
		Encapsulate "${EACH}"
	done
	declare -a BOOTTIME=();
	OIFS=$IFS
	IFS=$'\n'
	BOOTTIME=$(systemd-analyze blame) & Spinner "Analyzing Service(s) to blame sorted by time."
	BOOTTIME=($BOOTTIME)
	IFS=$OIFS
	Center "Service(s) to blame sorted by time."
	for EACH in "${BOOTTIME[@]}"
	do
		Encapsulate "${EACH}"
	done
	Center "Critical Chain."
	systemd-analyze critical-chain & Spinner "Analyzing critical-chain."
	Encapsulate "Generating graphical analysis."
	PLOTIT=$(systemd-analyze plot > ~/boot_analysis.svg) & Spinner "Generating graphical analysis."
	FullBar
	xdg-open ~/boot_analysis.svg
}

Services () {
	CheckRoot
	Encapsulate "${WARNING}WARNING: Disclaimer: I am not responsible for your actions. I highly suggest Goggle each and every service before masking it."
	Encapsulate "man ue-tweaker to learn more. Do you consent?"
	PromptYN "${WARNING}You can hit CTRL+C to break the program at any time. (Y/N)? "
		case "${YN}" in
			[Nn]* ) Encapsulate "Exiting..."
			exit 0;;
			[Yy]* ) ;;
		esac
	shopt -s nullglob
	declare -a SERVICES=();
	OIFS=$IFS
	IFS=$'\n'
	SERVICES=$(sudo systemd-analyze security | grep -i ".service" | awk '{ print $1 }' | sed "s/.service//g")
	SERVICES=($SERVICES)
	NSERVICES="${#SERVICES[@]}"
	IFS=$OIFS
	GREPIT=$(echo "$@" | grep -i "list")
	if ! [[ "${GREPIT}" ]]; then
		COUNTER=0
		Encapsulate "Number of services found: ${NSERVICES}"
		for EACH in "${SERVICES[@]}"
		do
			COUNTER=$((COUNTER + 1))
			FullBar
			Encapsulate "Scanning Status of service: ${EACH}"
			SSTATUS=$(systemctl list-unit-files | grep "${EACH}" | awk -F ' ' '{print $2}')
			if [[ "${SSTATUS}" ]]; then
				Encapsulate "Service Status: ${SSTATUS}"
			else
				Encapsulate "Service Status unknown."
			fi
			Encapsulate "Service ${COUNTER}: ${EACH} (d)isable, (k)eep, (m)ask"
			FullBar
			echo -e "${txtred}"
			while true; do
				read -r -p "WARNING: masking ${EACH} service will make it totally unavailible. (d/k/m):? " dkm
				case "${dkm}" in
					[Dd]* ) echo -e "${txtrst}"; sudo systemctl stop "${EACH}" ; sudo systemctl disable "${EACH}" ; break;;
					[Mm]* ) echo -e "${txtrst}"; sudo systemctl stop "${EACH}" ; sudo systemctl mask "${EACH}" ; break;;
					[Kk]* ) echo -e "${txtgrn}" ; break;;
					* ) echo "Please answer d, k or m.";;
				esac
			done
		done
	else
		COUNTER=0
		Encapsulate "Number of services found: ${NSERVICES}"
		FullBar
		for EACH in "${SERVICES[@]}"
		do
			COUNTER=$((COUNTER + 1))
			Encapsulate "Service ${COUNTER}: ${EACH}"
		done
		FullBar
	fi
}
# Help system - I have re-wrote this section to work with code-cleanup.
Help () {

	if [[ "${2}" == "" ]]; then
		VersionDump
		PRAM="ALL"
	else
		if ! [[ "${3}" ]]; then
			PRAM="${2}"
		else
			PRAM="${2}"
		fi
	fi

	case "${PRAM}" in
		ALL)
		Encapsulate "Usage: ${PROGNAME} -<-COMMAND> [OPTION]"
		FullBar
		Encapsulate "Mandatory arguments to long options are identical for short options."
		Encapsulate "  possible commands..."
		Encapsulate " "
		Encapsulate "  -b   --boottime   boottime analysis."
		Encapsulate "  -h   --help       this help message."
		Encapsulate "  -s   --services   tweak services."
		Encapsulate "  -v   --version    dump version info and exit."
		Encapsulate " "
		FullBar
		Center "${PROGNAME} --help [COMMAND] for further information."
		FullBar;;

		# Help Boottime
		ALL|b|boottime)
		Encapsulate "Usage boottime [OPTION]"
		FullBar
		Center "${PROGNAME} -b [OPTION]"
		FullBar
		FormatText "Analyzes the critical-chain, and looks for bottlenecks in your boottime.  Generates a graph of what is slowing down your system.  Knowledge of how services work is highly recommend.  This app will and can bork your entire Operating System.  Be prepared to re-install your O/S if you make an error.  You will learn each and every time.  I have in the past booted in less then 2 seconds."
		FullBar;;

		# Version Help
		ALL|v|version)
		Encapsulate "Usage version;"
		FullBar
		Center "${PROGNAME} -v"
		FullBar
		Encapsulate "Displays ${PROGNAME}s version number and exits."
		FullBar;;

		# Help Services
		ALL|s|services)
		Encapsulate "Usage services [OPTION]"
		FullBar
		Center "${PROGNAME} -s [OPTION]"
		FullBar
		FormatText "Disclaimer: I am not responsible for your actions. I highly suggest Goggle each and e very service before masking it. Allows the end user 3 options per service. It will prompt you on each and every service if you want to (k)eep, (d)isable or (m)ask service by service. Disabling a service technically is not disabling the service and probably should be the first action if you do not need the service. If the Operating System needs the service will still fire it up. If it is masked no matter what will not fire up that service. Masking services provides the lar gest gain in boot speed. For example you do not have a printer and have no intention of getting a printer. Masking cups is a huge gain. I do not think I can word it better then the way I did."
		Encapsulate " "
		Encapsulate "man ${PROGNAME}"
		Encapsulate " "
		Encapsulate "Example: ${PROGNAME} --service list"
		Encapsulate "Will display enabled / running services."
		FullBar;;

		# Help Help
		ALL|h|help|\?)
		Encapsulate "Usage Help [COMMAND]"
		FullBar
		Center "${PROGNAME} -h [COMMAND]"
		FullBar
		Encapsulate "Displays this message. For futher information ${PROGNAME} help [COMMAND]"
		Encapsulate "or refer to the manpages."
		Encapsulate " "
		Encapsulate "man ${PROGNAME}"
		Encapsulate " "
		Encapsulate "Example: ${PROGNAME} -h version"
		Encapsulate "Will display help about the command switch version"
		FullBar
	esac
	exit 0
}

TestBar () {
	CheckRoot
	Encapsulate "Testing Progress bar"
	i=0
	while [[ $i -ne 100 ]]
	do
		i=$(($i+1))
		ProgressBar "$i" "Testing Progress bar"
		sleep .1
	done

	CURRENTBRANCH=$(lsb_release -c | cut -d ":" -f2 | sed "s/ //g" | sed "s/	//g")
	MINIMAL=$(lsb_release -d | grep -i "minimal")
	SERVER=$(lsb_release -d | grep -i "server")
	if [[ "${CURRENTBRANCH}" ]]; then
		if [[ "${1}" == "DIST" ]]; then
			Encapsulate "Replacing ${CURRENTBRANCH} with Kinetic sources to distribution upgrade."
			sudo sed -i "s/${CURRENTBRANCH}/kinetic/g" "/etc/apt/sources.list"
			Center "Downloading Core files"
			if [[ "${MINIMAL}" || "${SERVER}" ]]; then
				Download "http://os-builder.com/7.7/ultimate-edition-7.7-minimal-server-core-files.deb"
			else
				Download "http://os-builder.com/7.7/ultimate-edition-7.7-developer-core-files.deb"
			fi
			Download "http://os-builder.com/7.7/ultimate-edition-grub-7.7_all.deb"
			if ! [[ "${MINIMAL}" || "${SERVER}" ]]; then
				Download "http://os-builder.com/7.7/ultimate-edition-plymouth-7.7_all.deb"
			fi
			if ! [[ "${MINIMAL}" || "${SERVER}" ]]; then
				Download "http://os-builder.com/7.7/ultimate-edition-theme-7.7_all.deb"
			fi
			sudo dpkg -i ultimate-edition-*.deb
		else
			Encapsulate "Replacing ${CURRENTBRANCH} with kinetic sources to get the latest kernel."
		fi
		sudo sed -i "s/${CURRENTBRANCH}/kinetic/g" "/etc/apt/sources.list"
		Encapsulate "Running apt-get update..."
		sudo apt-get update >/dev/null & Spinner "Running apt-get update..."
		Encapsulate "Installing latest low-latency kernel..."
		if ! [[ "${1}" == "DIST" ]]; then
			sudo DEBIAN_FRONTEND=noninteractive sudo apt-get install -f -y linux-lowlatency linux-headers-lowlatency linux-image-lowlatency & Spinner "Installing latest low-latency kernel..."
		else
			sudo apt-get dist-upgrade -f -y
		fi
		if ! [[ "${1}" == "DIST" ]]; then
			Encapsulate "Replacing kinetic sources back to ${CURRENTBRANCH}."
			sudo sed -i "s/kinetic/${CURRENTBRANCH}/g" "/etc/apt/sources.list"
			Encapsulate "Running apt-get update..."
			sudo apt-get update >/dev/null & Spinner "Running apt-get update..."
		else
			Encapsulate "Reboot to enjoy your new O/S."
		fi
	else
		Error "Current Branch not detected, exiting."
		exit 1;
	fi
}
if ! [[ "${SUPPRESS}" ]]; then
	VersionDump "$@"
	Timer "Start" "${APPNAME}"
fi
case "${1}" in
	-b|--boottime) BootTime "$@"; exit 0;;
	-d|--dist-upgrade) TestBar "DIST"; exit 0;; # undocumented switch.
	-s|--services) Services "$@"; exit 0;;
	-h|--help|-\?) Help "$@"; exit 0;; # TODO: Enhance this section.
	-k|--kernel) TestBar "$@"; exit 0;; # undocumented switch.
	-v|--version) VersionDump "$@"; exit 0;;
	*) Help; exit 0;;
esac


