#!/bin/bash
{
	#////////////////////////////////////
	# DietPi-Cron:
	#
	#////////////////////////////////////
	# Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com
	#
	#////////////////////////////////////
	#
	# Info:
	# - Menu system that allows users to change the start dates/times for all cron jobs.
	#
	# Usage:
	# - /DietPi/dietpi/dietpi-cron
	#////////////////////////////////////

	#Import DietPi-Globals ---------------------------------------------------------------
	. /DietPi/dietpi/func/dietpi-globals
	G_CHECK_ROOT_USER
	export G_PROGRAM_NAME='DietPi-Cron'
	#Import DietPi-Globals ---------------------------------------------------------------

	#/////////////////////////////////////////////////////////////////////////////////////
	#Globals
	#/////////////////////////////////////////////////////////////////////////////////////
	PROGRAM_NAME="DietPi-Cron"

	TARGETMENUID=0
	PREVIOUS_MENU_SELECTION="cron.hourly"
	OPTION=0
	CHOICE=0
	aCRON_TIME=()
	aDAY_OF_THE_WEEK_TEXT=(
		"Monday"
		"Tuesday"
		"Wednesday"
		"Thursday"
		"Friday"
		"Saturday"
		"Sunday"
		)

	Read_Cron_Times(){

		#hourly_min
		aCRON_TIME[0]=$(cat /etc/crontab | grep -m1 'cron.hourly' | awk '{print $1}')

		#daily_min / daily_hour
		aCRON_TIME[1]=$(cat /etc/crontab | grep -m1 'cron.daily' | awk '{print $1}')
		aCRON_TIME[2]=$(cat /etc/crontab | grep -m1 'cron.daily' | awk '{print $2}')

		#weekly_min / weekly_hour / weekly_day_of_week
		aCRON_TIME[3]=$(cat /etc/crontab | grep -m1 'cron.weekly' | awk '{print $1}')
		aCRON_TIME[4]=$(cat /etc/crontab | grep -m1 'cron.weekly' | awk '{print $2}')
		aCRON_TIME[5]=$(cat /etc/crontab | grep -m1 'cron.weekly' | awk '{print $5}')

		#monthly_min / monthly_hour / monthly_day_of_month
		aCRON_TIME[6]=$(cat /etc/crontab | grep -m1 'cron.monthly' | awk '{print $1}')
		aCRON_TIME[7]=$(cat /etc/crontab | grep -m1 'cron.monthly' | awk '{print $2}')
		aCRON_TIME[8]=$(cat /etc/crontab | grep -m1 'cron.monthly' | awk '{print $3}')

		#Check for valid ints
		for ((i=0; i<${#aCRON_TIME[@]}; i++))
		do
			if [[ ${aCRON_TIME[$i]} =~ ^-?[0-9]+$ ]]; then
				echo "valid" &> /dev/null
			else
				#override
				aCRON_TIME[$i]=1
			fi
		done

	}

	Write_Cron_Times(){

	cat << _EOF_ > /etc/crontab
#Please use dietpi-cron to change cron start times
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
${aCRON_TIME[0]} * * * *   root    cd / && run-parts --report /etc/cron.hourly
${aCRON_TIME[1]} ${aCRON_TIME[2]} * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
${aCRON_TIME[3]} ${aCRON_TIME[4]} * * ${aCRON_TIME[5]}   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
${aCRON_TIME[6]} ${aCRON_TIME[7]} ${aCRON_TIME[8]} * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
_EOF_

	}

	Input_Cron_Minute(){

		local input_value=$1
		local min_value=0
		local max_value=59

		OPTION=$(whiptail --inputbox "Please enter a value for MINUTE:\n - Valid range ($min_value - $max_value)" 9 50 "$input_value" --title "Set Minute" 3>&1 1>&2 2>&3)
		CHOICE=$?
		if (( $CHOICE == 0 )); then

			#Valid input?
			if [[ $OPTION =~ ^-?[0-9]+$ ]] &&
				(( $OPTION >= $min_value )) && (( $OPTION <= $max_value )); then
				input_value=$OPTION
			else
				Info_Input_Not_Valid_Integer
			fi
		fi

		return $input_value

	}

	Input_Cron_Hour(){

		local input_value=$1
		local min_value=0
		local max_value=23

		OPTION=$(whiptail --inputbox "Please enter a value for HOUR (24h):\n - Valid range ($min_value - $max_value)" 9 50 "$input_value" --title "Set Hour" 3>&1 1>&2 2>&3)
		CHOICE=$?
		if (( $CHOICE == 0 )); then

			#Valid input?
			if [[ $OPTION =~ ^-?[0-9]+$ ]] &&
				(( $OPTION >= $min_value )) && (( $OPTION <= $max_value )); then
				input_value=$OPTION
			else
				Info_Input_Not_Valid_Integer
			fi
		fi

		return $input_value

	}

	Input_Cron_DayOfWeek(){

		local input_value=$1
		local min_value=1
		local max_value=7

		OPTION=$(whiptail --title "Day of the Week" --menu "Please select a day of the week." --cancel-button "Cancel" --default-item "$input_value" 15 45 7 \
		"1" "${aDAY_OF_THE_WEEK_TEXT[0]}" \
		"2" "${aDAY_OF_THE_WEEK_TEXT[1]}" \
		"3" "${aDAY_OF_THE_WEEK_TEXT[2]}" \
		"4" "${aDAY_OF_THE_WEEK_TEXT[3]}" \
		"5" "${aDAY_OF_THE_WEEK_TEXT[4]}" \
		"6" "${aDAY_OF_THE_WEEK_TEXT[5]}" \
		"7" "${aDAY_OF_THE_WEEK_TEXT[6]}" 3>&1 1>&2 2>&3)

		if (( $CHOICE == 0 )); then
			input_value=$OPTION
		fi

		return $input_value

	}

	Input_Cron_DayOfMonth(){

		local input_value=$1
		local min_value=1
		local max_value=28

		OPTION=$(whiptail --inputbox "Please enter a value for DAY of the MONTH:\n - Valid range ($min_value - $max_value)\n - eg: 11 = the 11th day of month" 10 50 "$input_value" --title "Set Day of Month" 3>&1 1>&2 2>&3)
		CHOICE=$?
		if (( $CHOICE == 0 )); then

			#Valid input?
			if [[ $OPTION =~ ^-?[0-9]+$ ]] &&
				(( $OPTION >= $min_value )) && (( $OPTION <= $max_value )); then
				input_value=$OPTION
			else
				Info_Input_Not_Valid_Integer
			fi
		fi

		return $input_value

	}


	Info_Input_Not_Valid_Integer(){
		whiptail --title "Invalid Value" --msgbox "$OPTION is an invalid value." --backtitle "$WHIP_BACKTITLE" 9 60
	}

	Menu_Exit(){

		whiptail --title "Exit $PROGRAM_NAME?" --yesno "Exit $PROGRAM_NAME?" --backtitle "$PROGRAM_NAME" --yes-button "Ok" --no-button "Back" --defaultno 9 55
		CHOICE=$?
		if (( $CHOICE == 0 )); then
			#exit
			TARGETMENUID=-1
		else
			#Return to Main Menu
			TARGETMENUID=0
		fi
	}

	Menu_Main(){

		OPTION=$(whiptail --title "$PROGRAM_NAME" --menu "This program allows you to change the date and times for starting each cron job.\n\n- Example:\nIf you set cron.daily to 22 hours and 20 minutes, all scripts in /etc/cron.daily/* will be run at 10:20pm" --cancel-button "Exit" --default-item "$PREVIOUS_MENU_SELECTION" --backtitle "$PROGRAM_NAME" 18 70 5 \
		"cron.hourly" "Every Hour at ${aCRON_TIME[0]} Minutes" \
		"cron.daily" "Every Day at ${aCRON_TIME[2]} Hours and ${aCRON_TIME[1]} Minutes" \
		"cron.weekly" "Every ${aDAY_OF_THE_WEEK_TEXT[$(( ${aCRON_TIME[5]} - 1))]} at ${aCRON_TIME[4]} Hours and ${aCRON_TIME[3]} Minutes" \
		"cron.monthly" "On Day ${aCRON_TIME[8]} of the month at ${aCRON_TIME[7]} Hours and ${aCRON_TIME[6]} Minutes" \
		"Apply" "Saves your cron start times and restarts service." 3>&1 1>&2 2>&3)

		CHOICE=$?
		if (( $CHOICE == 0 )); then

			PREVIOUS_MENU_SELECTION=$OPTION

			case "$OPTION" in
				"cron.hourly")
					Input_Cron_Minute ${aCRON_TIME[0]}
					aCRON_TIME[0]=$?
				;;
				"cron.daily")
					Input_Cron_Hour ${aCRON_TIME[2]}
					aCRON_TIME[2]=$?

					Input_Cron_Minute ${aCRON_TIME[1]}
					aCRON_TIME[1]=$?
				;;
				"cron.weekly")
					Input_Cron_DayOfWeek ${aCRON_TIME[5]}
					aCRON_TIME[5]=$?

					Input_Cron_Hour ${aCRON_TIME[4]}
					aCRON_TIME[4]=$?

					Input_Cron_Minute ${aCRON_TIME[3]}
					aCRON_TIME[3]=$?
				;;
				"cron.monthly")
					Input_Cron_DayOfMonth ${aCRON_TIME[8]}
					aCRON_TIME[8]=$?

					Input_Cron_Hour ${aCRON_TIME[7]}
					aCRON_TIME[7]=$?

					Input_Cron_Minute ${aCRON_TIME[6]}
					aCRON_TIME[6]=$?
				;;
				"Apply")
					Write_Cron_Times
					#restart service
					systemctl restart cron

					#inform user
					whiptail --title "Completed" --msgbox "Your Cron start times have been saved and applied." 9 60
				;;
			esac

		else
			#Exit
			Menu_Exit
		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# Main Loop
	#/////////////////////////////////////////////////////////////////////////////////////
	#Get current values
	Read_Cron_Times
	#-----------------------------------------------------------------------------------
	#Start Menu
	while (( $TARGETMENUID > -1 )); do

		#Clear Screen buffer
		clear

		if (( $TARGETMENUID == 0 )); then
			Menu_Main
		fi

	done
	#-----------------------------------------------------------------------------------
	#delete[]
	unset aDAY_OF_THE_WEEK_TEXT
	unset aCRON_TIME
	#-----------------------------------------------------------------------------------
	exit
	#-----------------------------------------------------------------------------------
}