/*
 * Copyright (c) 2017 Linaro Limited
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_sntp, CONFIG_SNTP_LOG_LEVEL);

#include <zephyr/net/sntp.h>
#include "sntp_pkt.h"
#include <limits.h>

#define SNTP_LI_MAX 3
#define SNTP_VERSION_NUMBER 3
#define SNTP_MODE_CLIENT 3
#define SNTP_MODE_SERVER 4
#define SNTP_STRATUM_KOD 0 /* kiss-o'-death */
#define OFFSET_1970_JAN_1 2208988800

static void sntp_pkt_dump(struct sntp_pkt *pkt)
{
	if (!pkt) {
		return;
	}

	NET_DBG("li               %x", pkt->li);
	NET_DBG("vn               %x", pkt->vn);
	NET_DBG("mode             %x", pkt->mode);
	NET_DBG("stratum:         %x", pkt->stratum);
	NET_DBG("poll:            %x", pkt->poll);
	NET_DBG("precision:       %x", pkt->precision);
	NET_DBG("root_delay:      %x", ntohl(pkt->root_delay));
	NET_DBG("root_dispersion: %x", ntohl(pkt->root_dispersion));
	NET_DBG("ref_id:          %x", ntohl(pkt->ref_id));
	NET_DBG("ref_tm_s:        %x", ntohl(pkt->ref_tm_s));
	NET_DBG("ref_tm_f:        %x", ntohl(pkt->ref_tm_f));
	NET_DBG("orig_tm_s:       %x", ntohl(pkt->orig_tm_s));
	NET_DBG("orig_tm_f:       %x", ntohl(pkt->orig_tm_f));
	NET_DBG("rx_tm_s:         %x", ntohl(pkt->rx_tm_s));
	NET_DBG("rx_tm_f:         %x", ntohl(pkt->rx_tm_f));
	NET_DBG("tx_tm_s:         %x", ntohl(pkt->tx_tm_s));
	NET_DBG("tx_tm_f:         %x", ntohl(pkt->tx_tm_f));
}

#if defined(CONFIG_SNTP_UNCERTAINTY)
static int64_t q16_16_s_to_ll_us(uint32_t t)
{
	return (int64_t)(t >> 16) * (int64_t)USEC_PER_SEC +
	       (((int64_t)(t & 0xFFFF) * (int64_t)USEC_PER_SEC) >> 16);
}

static int64_t q32_32_s_to_ll_us(uint32_t t_s, uint32_t t_f)
{
	return (uint64_t)t_s * USEC_PER_SEC + (((uint64_t)t_f * (uint64_t)USEC_PER_SEC) >> 32);
}
#endif

static int32_t parse_response(uint8_t *data, uint16_t len, struct sntp_time *expected_orig_ts,
			      struct sntp_time *res)
{
	struct sntp_pkt *pkt = (struct sntp_pkt *)data;
	uint32_t ts;

	sntp_pkt_dump(pkt);

	if (ntohl(pkt->orig_tm_s) != expected_orig_ts->seconds ||
	    ntohl(pkt->orig_tm_f) != expected_orig_ts->fraction) {
		NET_DBG("Mismatch originate timestamp: %d.%09d, expect: %llu.%09u",
			ntohl(pkt->orig_tm_s), ntohl(pkt->orig_tm_f), expected_orig_ts->seconds,
			expected_orig_ts->fraction);
		return -EINVAL;
	}

	if (pkt->mode != SNTP_MODE_SERVER) {
		/* For unicast and manycast, server should return 4.
		 * For broadcast (which is not supported now), server should
		 * return 5.
		 */
		NET_DBG("Unexpected mode: %d", pkt->mode);
		return -EINVAL;
	}

	if (pkt->stratum == SNTP_STRATUM_KOD) {
		NET_DBG("kiss-o'-death stratum");
		return -EBUSY;
	}

	if (ntohl(pkt->tx_tm_s) == 0 && ntohl(pkt->tx_tm_f) == 0) {
		NET_DBG("zero transmit timestamp");
		return -EINVAL;
	}

#if defined(CONFIG_SNTP_UNCERTAINTY)

	int64_t dest_ts_us = k_ticks_to_us_near64(k_uptime_ticks());
	int64_t orig_ts_us =
		q32_32_s_to_ll_us(expected_orig_ts->seconds, expected_orig_ts->fraction);

	int64_t rx_ts_us = q32_32_s_to_ll_us(ntohl(pkt->rx_tm_s), ntohl(pkt->rx_tm_f));
	int64_t tx_ts_us = q32_32_s_to_ll_us(ntohl(pkt->tx_tm_s), ntohl(pkt->tx_tm_f));

	if (rx_ts_us > tx_ts_us || orig_ts_us > dest_ts_us) {
		NET_DBG("Invalid timestamps from SNTP server");
		return -EINVAL;
	}

	int64_t d_us = (dest_ts_us - orig_ts_us) - (tx_ts_us - rx_ts_us);
	int64_t clk_offset_us = ((rx_ts_us - orig_ts_us) + (tx_ts_us - dest_ts_us)) / 2;
	int64_t root_dispersion_us = q16_16_s_to_ll_us(ntohl(pkt->root_dispersion));
	int64_t root_delay_us = q16_16_s_to_ll_us(ntohl(pkt->root_delay));
	uint32_t precision_us;

	if (pkt->precision <= 0) {
		precision_us = (uint32_t)(USEC_PER_SEC + USEC_PER_SEC / 2) >> -pkt->precision;
	} else if (pkt->precision <= 10) {
		precision_us = (uint32_t)(USEC_PER_SEC + USEC_PER_SEC / 2) << pkt->precision;
	} else {
		NET_DBG("SNTP packet precision out of range: %d", pkt->precision);
		return -EINVAL;
	}

	res->uptime_us = dest_ts_us;
	res->seconds = (res->uptime_us + clk_offset_us) / USEC_PER_SEC;
	res->fraction = (res->uptime_us + clk_offset_us) % USEC_PER_SEC;
	res->uncertainty_us = (d_us + root_delay_us + precision_us) / 2 + root_dispersion_us;
#else
	res->fraction = ntohl(pkt->tx_tm_f);
	res->seconds = ntohl(pkt->tx_tm_s);
#endif
	ts = ntohl(pkt->tx_tm_s);

	/* Check if most significant bit is set */
	if (ts & 0x80000000) {
		/* UTC time is reckoned from 0h 0m 0s UTC
		 * on 1 January 1900.
		 */
		if (ts >= OFFSET_1970_JAN_1) {
			res->seconds -= OFFSET_1970_JAN_1;
		} else {
			return -EINVAL;
		}
	} else {
		/* UTC time is reckoned from 6h 28m 16s UTC
		 * on 7 February 2036.
		 */
		res->seconds += 0x100000000ULL - OFFSET_1970_JAN_1;
	}

	return 0;
}

static int sntp_recv_response(struct sntp_ctx *sntp, uint32_t timeout,
			      struct sntp_time *time)
{
	struct sntp_pkt buf = { 0 };
	int status;
	int rcvd;

	status = zsock_poll(sntp->sock.fds, sntp->sock.nfds, timeout);
	if (status < 0) {
		NET_ERR("Error in poll:%d", errno);
		return -errno;
	}

	if (status == 0) {
		return -ETIMEDOUT;
	}

	rcvd = zsock_recv(sntp->sock.fd, (uint8_t *)&buf, sizeof(buf), 0);
	if (rcvd < 0) {
		return -errno;
	}

	if (rcvd != sizeof(struct sntp_pkt)) {
		return -EMSGSIZE;
	}

	status = parse_response((uint8_t *)&buf, sizeof(buf),
				&sntp->expected_orig_ts,
				time);
	return status;
}

int sntp_init(struct sntp_ctx *ctx, struct sockaddr *addr, socklen_t addr_len)
{
	int ret;

	if (!ctx || !addr) {
		return -EFAULT;
	}

	memset(ctx, 0, sizeof(struct sntp_ctx));

	ctx->sock.fd = zsock_socket(addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
	if (ctx->sock.fd < 0) {
		NET_ERR("Failed to create UDP socket %d", errno);
		return -errno;
	}

	ret = zsock_connect(ctx->sock.fd, addr, addr_len);
	if (ret < 0) {
		(void)zsock_close(ctx->sock.fd);
		NET_ERR("Cannot connect to UDP remote : %d", errno);
		return -errno;
	}

	ctx->sock.fds[ctx->sock.nfds].fd = ctx->sock.fd;
	ctx->sock.fds[ctx->sock.nfds].events = ZSOCK_POLLIN;
	ctx->sock.nfds++;

	return 0;
}

int sntp_query(struct sntp_ctx *ctx, uint32_t timeout, struct sntp_time *time)
{
	struct sntp_pkt tx_pkt = { 0 };
	int ret = 0;
	int64_t ts_us = 0;

	if (!ctx || !time) {
		return -EFAULT;
	}

	/* prepare request pkt */
	tx_pkt.li = 0;
	tx_pkt.vn = SNTP_VERSION_NUMBER;
	tx_pkt.mode = SNTP_MODE_CLIENT;
	ts_us = k_ticks_to_us_near64(k_uptime_ticks());
	ctx->expected_orig_ts.seconds = ts_us / USEC_PER_SEC;
	ctx->expected_orig_ts.fraction = (ts_us % USEC_PER_SEC) * (UINT32_MAX / USEC_PER_SEC);
	tx_pkt.tx_tm_s = htonl(ctx->expected_orig_ts.seconds);
	tx_pkt.tx_tm_f = htonl(ctx->expected_orig_ts.fraction);

	ret = zsock_send(ctx->sock.fd, (uint8_t *)&tx_pkt, sizeof(tx_pkt), 0);
	if (ret < 0) {
		NET_ERR("Failed to send over UDP socket %d", ret);
		return ret;
	}

	return sntp_recv_response(ctx, timeout, time);
}

void sntp_close(struct sntp_ctx *ctx)
{
	if (ctx) {
		(void)zsock_close(ctx->sock.fd);
	}
}
