#!/bin/sh

# Script to activate image in specified time.
#
# Copyright © 2022 -  2025 IOPSYS Software Solutions AB
# Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
#

. /usr/share/libubox/jshn.sh
ROOT="$(dirname "${0}")"

CHECK_IDLE_FILE="${ROOT}/bbf_check_idle.sh"
RETRY_TIME=300
START_TIME=$(date +%s)
MODE=""

log() {
    echo "${@}"|logger -t bbf.activate_firmware -p info
}

activate_and_reboot_device() {
	local bank_id="${1}"; shift
	local keep_settings="${1}"; shift
	local keep_opconf="${1}"; shift
	local config_scope="${1}"; shift
	local success

	success=$(ubus call fwbank set_bootbank "{'bank':${bank_id}}" | jsonfilter -e @.success)
	if [ "${success}" != "true" ]; then
		log "Can't activate the bank id ${bank_id}"
		exit 1
	fi

	json_init
	[ -n "${keep_settings}" ] && json_add_boolean "keep_settings" "${keep_settings}"
	[ -n "${keep_opconf}" ] && json_add_boolean "keep_opconf" "${keep_opconf}"
	[ -n "${config_scope}" ] && json_add_string "config_scope" "${config_scope}"

	success=$(json_dump| /etc/sysmngr/fwbank call copy_config 2> /dev/null | jsonfilter -e @.success)
	if [ "${success}" != "true" ]; then
		log "Can't copy config"
		exit 1
	fi

	log "The device will restart after a few seconds"
	ubus call rpc-sys reboot
	exit 0
}

handle_whenidle_mode() {
	local bank_id="${1}"
	local end_time="${2}"
	local force_activation="${3}"
	local keep_settings="${4}"
	local keep_opconf="${5}"
	local config_scope="${6}"
	local diff=0
	
	[ ! -x "${CHECK_IDLE_FILE}" ] && {
		activate_and_reboot_device "${bank_id}" "${keep_settings}" "${keep_opconf}" "${config_scope}"
	}

	sh "${CHECK_IDLE_FILE}"
	if [ "$?" = "0" ]; then
		activate_and_reboot_device "${bank_id}" "${keep_settings}" "${keep_opconf}" "${config_scope}"
	else
		[ "${end_time}" -gt "$((diff + RETRY_TIME))" ] && {
			sleep "${RETRY_TIME}"
		}

		diff=$(($(date +%s) - START_TIME))
	fi

	while [ "${end_time}" -gt "${diff}" ]; do
		sh "${CHECK_IDLE_FILE}"
		if [ "$?" = "0" ]; then
			activate_and_reboot_device "${bank_id}" "${keep_settings}" "${keep_opconf}" "${config_scope}"
		else

			if [ "${end_time}" -gt "$((diff + RETRY_TIME))" ]; then
				sleep "${RETRY_TIME}"
			else
				break
			fi

			diff=$(($(date +%s) - START_TIME))
		fi

	done

	[ "${force_activation}" = "1" ] && {
		activate_and_reboot_device "${bank_id}" "${keep_settings}" "${keep_opconf}" "${config_scope}"
	}
}

handle_confirmation_needed_mode() {

	log "[ConfirmationNeeded] mode is not implemented"
	exit 0
}

######################## main ########################
if [ "$#" -lt "8" ]; then
	log "Invalid inputs [$*]"
	exit 1
fi

MODE="${1}"; shift
BANKID="${1}"; shift
ENDTIME="${1}"; shift
LASTWINDOW="${1}"; shift
MAXRETRIES="${1}"; shift
KEEPCONFIG="${1}"; shift
KEEPOPCONF="${1}"; shift
CONFIGSCOPE="${1}"; shift
MSG="$*"

if [ "${MODE}" = "Immediately" ] || [ "${MODE}" = "AnyTime" ]; then
	activate_and_reboot_device "${BANKID}" "${KEEPCONFIG}" "${KEEPOPCONF}" "${CONFIGSCOPE}"
elif [ "${MODE}" = "WhenIdle" ]; then
	handle_whenidle_mode "${BANKID}" "${ENDTIME}" "${LASTWINDOW}" "${KEEPCONFIG}" "${KEEPOPCONF}" "${CONFIGSCOPE}"
elif [ "${MODE}" = "ConfirmationNeeded" ]; then
	handle_confirmation_needed_mode "${BANKID}" "${ENDTIME}" "${LASTWINDOW}" "${MAXRETRIES}" "${KEEPCONFIG}" "${KEEPOPCONF}" "${CONFIGSCOPE}" "${MSG}"
else
	log "[${MODE}] mode is not supported"
	exit 1
fi
