#!/bin/bash
do {
	#////////////////////////////////////
	# 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 ---------------------------------------------------------------
	source /DietPi/dietpi/func/dietpi-globals
	G_CHECK_ROOT_USER
	export G_PROGRAM_NAME='DietPi-Cron'
	#Import DietPi-Globals ---------------------------------------------------------------

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

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

	proc Read_Cron_Times {

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

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

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

		#monthly_min / monthly_hour / monthly_day_of_month
		setvar aCRON_TIME[6]=$(cat /etc/crontab | grep -m1 'cron.monthly' | awk '{print $1}')
		setvar aCRON_TIME[7]=$(cat /etc/crontab | grep -m1 'cron.monthly' | awk '{print $2}')
		setvar 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

	}

	proc Write_Cron_Times {

	cat <<< """ > /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 )
"""
> /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_

	}

	proc Input_Cron_Minute {

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

		setvar 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)
		setvar CHOICE = ""$?
		if (( $CHOICE == 0 )) {

			#Valid input?
			if [[ $OPTION =~ ^-?[0-9]+$ ]] &&
				(( $OPTION >= $min_value )) && (( $OPTION <= $max_value )) {
				setvar input_value = "$OPTION"
			} else {
				Info_Input_Not_Valid_Integer
			}
		}

		return $input_value

	}

	proc Input_Cron_Hour {

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

		setvar 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)
		setvar CHOICE = ""$?
		if (( $CHOICE == 0 )) {

			#Valid input?
			if [[ $OPTION =~ ^-?[0-9]+$ ]] &&
				(( $OPTION >= $min_value )) && (( $OPTION <= $max_value )) {
				setvar input_value = "$OPTION"
			} else {
				Info_Input_Not_Valid_Integer
			}
		}

		return $input_value

	}

	proc Input_Cron_DayOfWeek {

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

		setvar 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 )) {
			setvar input_value = "$OPTION"
		}

		return $input_value

	}

	proc Input_Cron_DayOfMonth {

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

		setvar 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)
		setvar CHOICE = ""$?
		if (( $CHOICE == 0 )) {

			#Valid input?
			if [[ $OPTION =~ ^-?[0-9]+$ ]] &&
				(( $OPTION >= $min_value )) && (( $OPTION <= $max_value )) {
				setvar input_value = "$OPTION"
			} else {
				Info_Input_Not_Valid_Integer
			}
		}

		return $input_value

	}


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

	proc Menu_Exit {

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

	proc Menu_Main {

		setvar 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)

		setvar CHOICE = ""$?
		if (( $CHOICE == 0 )) {

			setvar PREVIOUS_MENU_SELECTION = "$OPTION"

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

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

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

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

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

					Input_Cron_Minute ${aCRON_TIME[6]}
					setvar 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
				}
			}

		} else {
			#Exit
			Menu_Exit
		}

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# Main Loop
	#/////////////////////////////////////////////////////////////////////////////////////
	#Get current values
	Read_Cron_Times {

		#Clear Screen buffer
		clear

		if (( $TARGETMENUID == 0 )) {
			Menu_Main
		}

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