/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <net/net_timeout.h>
#include <sys_clock.h>

void net_timeout_set(struct net_timeout *timeout,
		     uint32_t lifetime,
		     uint32_t now)
{
	uint64_t expire_timeout;

	timeout->timer_start = now;

	/* Highly unlikely, but a zero timeout isn't correctly handled by the
	 * standard calculation.
	 */
	if (lifetime == 0U) {
		timeout->wrap_counter = 0;
		timeout->timer_timeout = 0;
		return;
	}

	expire_timeout = (uint64_t)MSEC_PER_SEC * (uint64_t)lifetime;
	timeout->wrap_counter = expire_timeout /
		(uint64_t)NET_TIMEOUT_MAX_VALUE;
	timeout->timer_timeout = expire_timeout -
		(uint64_t)NET_TIMEOUT_MAX_VALUE *
		(uint64_t)timeout->wrap_counter;

	/* The implementation requires that the fractional timeout be zero
	 * only when the timeout has completed, so if the residual is zero
	 * copy over one timeout from the wrap.
	 */
	if (timeout->timer_timeout == 0U) {
		timeout->timer_timeout = NET_TIMEOUT_MAX_VALUE;
		timeout->wrap_counter -= 1;
	}
}

int64_t net_timeout_deadline(const struct net_timeout *timeout,
			     int64_t now)
{
	uint64_t start;
	uint64_t deadline;

	/* Reconstruct the full-precision start time assuming that the full
	 * precision start time is less than 2^32 ticks in the past.
	 */
	start = (uint64_t)now;
	start -= (uint32_t)now - timeout->timer_start;

	/* Offset the start time by the full precision remaining delay. */
	deadline = start + timeout->timer_timeout;
	deadline += (uint64_t)NET_TIMEOUT_MAX_VALUE
		* (uint64_t)timeout->wrap_counter;

	return (int64_t)deadline;
}

uint32_t net_timeout_remaining(const struct net_timeout *timeout,
			       uint32_t now)
{
	int64_t ret = timeout->timer_timeout;

	ret += timeout->wrap_counter * (uint64_t)NET_TIMEOUT_MAX_VALUE;
	ret -= (int64_t)(int32_t)(now - timeout->timer_start);
	if (ret <= 0) {
		return 0;
	}

	return (uint32_t)((uint64_t)ret / MSEC_PER_SEC);
}

uint32_t net_timeout_evaluate(struct net_timeout *timeout,
			      uint32_t now)
{
	uint32_t elapsed;
	uint32_t last_delay;
	int32_t remains;
	bool wraps;

	/* Time since last evaluation or set. */
	elapsed = now - timeout->timer_start;

	/* The delay used the last time this was evaluated. */
	wraps = (timeout->wrap_counter > 0U);
	last_delay = wraps
		? NET_TIMEOUT_MAX_VALUE
		: timeout->timer_timeout;

	/* Time remaining until completion of the last delay. */
	remains = (int32_t)(last_delay - elapsed);

	/* If the deadline for the next event hasn't been reached yet just
	 * return the remaining time.
	 */
	if (remains > 0) {
		return (uint32_t)remains;
	}

	/* Deadline has been reached.  If we're not wrapping we've completed
	 * the last portion of the full timeout, so return zero to indicate
	 * the timeout has completed.
	 */
	if (!wraps) {
		return 0U;
	}

	/* There's more to do.  We need to update timer_start to correspond to
	 * now, then reduce the remaining time by the elapsed time.  We know
	 * that's at least NET_TIMEOUT_MAX_VALUE, and can apply the
	 * reduction by decrementing the wrap count.
	 */
	timeout->timer_start = now;
	elapsed -= NET_TIMEOUT_MAX_VALUE;
	timeout->wrap_counter -= 1;

	/* The residual elapsed must reduce timer_timeout, which is capped at
	 * NET_TIMEOUT_MAX_VALUE.  But if subtracting would reduce the
	 * counter to zero or go negative we need to reduce the the wrap
	 * counter once more and add the residual to the counter, so the
	 * counter remains positive.
	 */
	if (timeout->timer_timeout > elapsed) {
		timeout->timer_timeout -= elapsed;
	} else {
		timeout->timer_timeout += NET_TIMEOUT_MAX_VALUE - elapsed;
		timeout->wrap_counter -= 1U;
	}

	return (timeout->wrap_counter == 0U)
		? timeout->timer_timeout
		: NET_TIMEOUT_MAX_VALUE;
}
