/*
 * Copyright (c) 2022 Martin Jäger <martin@libre.solar>
 * Copyright (c) 2022 tado GmbH
 *
 * Parts of this implementation were inspired by LmhpClockSync.c from the
 * LoRaMac-node firmware repository https://github.com/Lora-net/LoRaMac-node
 * written by Miguel Luis (Semtech).
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "lorawan_services.h"

#include <LoRaMac.h>
#include <zephyr/kernel.h>
#include <zephyr/lorawan/lorawan.h>
#include <zephyr/logging/log.h>
#include <zephyr/random/rand32.h>

LOG_MODULE_REGISTER(lorawan_clock_sync, CONFIG_LORAWAN_SERVICES_LOG_LEVEL);

/**
 * Version of LoRaWAN Application Layer Clock Synchronization Specification
 *
 * This implementation only supports TS003-2.0.0, as the previous revision TS003-1.0.0
 * requested to temporarily disable ADR and and set nb_trans to 1. This causes issues on the
 * server side and is not recommended anymore.
 */
#define CLOCK_SYNC_PACKAGE_VERSION 2

/* Maximum length of clock sync answers */
#define MAX_CLOCK_SYNC_ANS_LEN 6

/* Delay between consecutive transmissions of AppTimeReq */
#define CLOCK_RESYNC_DELAY 10

enum clock_sync_commands {
	CLOCK_SYNC_CMD_PKG_VERSION                 = 0x00,
	CLOCK_SYNC_CMD_APP_TIME                    = 0x01,
	CLOCK_SYNC_CMD_DEVICE_APP_TIME_PERIODICITY = 0x02,
	CLOCK_SYNC_CMD_FORCE_DEVICE_RESYNC         = 0x03,
};

struct clock_sync_context {
	/** Work item for regular (re-)sync requests (uplink messages) */
	struct k_work_delayable resync_work;
	/** Continuously incremented token to map clock sync answers and requests */
	uint8_t req_token;
	/** Number of requested clock sync requests left to be transmitted */
	uint8_t nb_transmissions;
	/**
	 * Offset to be added to system uptime to get GPS time (as used by LoRaWAN)
	 */
	uint32_t time_offset;
	/**
	 * AppTimeReq retransmission interval in seconds
	 *
	 * Valid range between 128 (0x80) and 8388608 (0x800000)
	 */
	uint32_t periodicity;
	/** Indication if at least one valid time correction was received */
	bool synchronized;
};

static struct clock_sync_context ctx;

/**
 * Writes the DeviceTime into the buffer.
 *
 * @returns number of bytes written or -ENOSPC in case of error
 */
static int clock_sync_serialize_device_time(uint8_t *buf, size_t size)
{
	uint32_t device_time = k_uptime_get() / MSEC_PER_SEC + ctx.time_offset;

	if (size < sizeof(uint32_t)) {
		return -ENOSPC;
	}

	buf[0] = (device_time >> 0) & 0xFF;
	buf[1] = (device_time >> 8) & 0xFF;
	buf[2] = (device_time >> 16) & 0xFF;
	buf[3] = (device_time >> 24) & 0xFF;

	return sizeof(uint32_t);
}

static void clock_sync_package_callback(uint8_t port, bool data_pending, int16_t rssi, int8_t snr,
					uint8_t len, const uint8_t *rx_buf)
{
	uint8_t tx_buf[3 * MAX_CLOCK_SYNC_ANS_LEN];
	uint8_t tx_pos = 0;
	uint8_t rx_pos = 0;

	__ASSERT(port == LORAWAN_PORT_CLOCK_SYNC, "Wrong port %d", port);

	while (rx_pos < len) {
		uint8_t command_id = rx_buf[rx_pos++];

		if (sizeof(tx_buf) - tx_pos < MAX_CLOCK_SYNC_ANS_LEN) {
			LOG_ERR("insufficient tx_buf size, some requests discarded");
			break;
		}

		switch (command_id) {
		case CLOCK_SYNC_CMD_PKG_VERSION:
			tx_buf[tx_pos++] = CLOCK_SYNC_CMD_PKG_VERSION;
			tx_buf[tx_pos++] = LORAWAN_PACKAGE_ID_CLOCK_SYNC;
			tx_buf[tx_pos++] = CLOCK_SYNC_PACKAGE_VERSION;
			LOG_DBG("PackageVersionReq");
			break;
		case CLOCK_SYNC_CMD_APP_TIME: {
			/* answer from application server */
			int32_t time_correction;

			ctx.nb_transmissions = 0;

			time_correction = rx_buf[rx_pos++];
			time_correction	+= rx_buf[rx_pos++] << 8;
			time_correction	+= rx_buf[rx_pos++] << 16;
			time_correction	+= rx_buf[rx_pos++] << 24;

			uint8_t token = rx_buf[rx_pos++] & 0x0F;

			if (token == ctx.req_token) {
				ctx.time_offset += time_correction;
				ctx.req_token = (ctx.req_token + 1) % 16;
				ctx.synchronized = true;

				LOG_DBG("AppTimeAns time_correction %d (token %d)",
					time_correction, token);
			} else {
				LOG_WRN("AppTimeAns with outdated token %d", token);
			}
			break;
		}
		case CLOCK_SYNC_CMD_DEVICE_APP_TIME_PERIODICITY: {
			uint8_t period = rx_buf[rx_pos++] & 0x0F;

			ctx.periodicity = 1U << (period + 7);

			tx_buf[tx_pos++] = CLOCK_SYNC_CMD_DEVICE_APP_TIME_PERIODICITY;
			tx_buf[tx_pos++] = 0x00; /* Status: OK */

			tx_pos += clock_sync_serialize_device_time(tx_buf + tx_pos,
								   sizeof(tx_buf) - tx_pos);

			LOG_DBG("DeviceAppTimePeriodicityReq period: %u", period);
			break;
		}
		case CLOCK_SYNC_CMD_FORCE_DEVICE_RESYNC: {
			uint8_t nb_transmissions = rx_buf[rx_pos++] & 0x07;

			if (nb_transmissions != 0) {
				ctx.nb_transmissions = nb_transmissions;
				lorawan_services_reschedule_work(&ctx.resync_work, K_NO_WAIT);
			}

			LOG_DBG("ForceDeviceResyncCmd nb_transmissions: %u", nb_transmissions);
			break;
		}
		default:
			return;
		}
	}

	if (tx_pos > 0) {
		lorawan_services_schedule_uplink(LORAWAN_PORT_CLOCK_SYNC, tx_buf, tx_pos, 0);
	}
}

static int clock_sync_app_time_req(void)
{
	uint8_t tx_pos = 0;
	uint8_t tx_buf[6];

	tx_buf[tx_pos++] = CLOCK_SYNC_CMD_APP_TIME;
	tx_pos += clock_sync_serialize_device_time(tx_buf + tx_pos,
						       sizeof(tx_buf) - tx_pos);

	/* Param: AnsRequired = 0 | TokenReq */
	tx_buf[tx_pos++] = ctx.req_token;

	LOG_DBG("Sending clock sync AppTimeReq (token %d)", ctx.req_token);

	lorawan_services_schedule_uplink(LORAWAN_PORT_CLOCK_SYNC, tx_buf, tx_pos, 0);

	if (ctx.nb_transmissions > 0) {
		ctx.nb_transmissions--;
		lorawan_services_reschedule_work(&ctx.resync_work, K_SECONDS(CLOCK_RESYNC_DELAY));
	}

	return 0;
}

static void clock_sync_resync_handler(struct k_work *work)
{
	uint32_t periodicity;

	clock_sync_app_time_req();

	/* Add +-30s jitter to actual periodicity as required */
	periodicity = ctx.periodicity - 30 + sys_rand32_get() % 61;

	lorawan_services_reschedule_work(&ctx.resync_work, K_SECONDS(periodicity));
}

int lorawan_clock_sync_get(uint32_t *gps_time)
{
	__ASSERT(gps_time != NULL, "gps_time parameter is required");

	if (ctx.synchronized) {
		*gps_time = (uint32_t)(k_uptime_get() / MSEC_PER_SEC + ctx.time_offset);
		return 0;
	} else {
		return -EAGAIN;
	}
}

static struct lorawan_downlink_cb downlink_cb = {
	.port = (uint8_t)LORAWAN_PORT_CLOCK_SYNC,
	.cb = clock_sync_package_callback
};

int lorawan_clock_sync_run(void)
{
	ctx.periodicity = CONFIG_LORAWAN_APP_CLOCK_SYNC_PERIODICITY;

	lorawan_register_downlink_callback(&downlink_cb);

	k_work_init_delayable(&ctx.resync_work, clock_sync_resync_handler);
	lorawan_services_reschedule_work(&ctx.resync_work, K_NO_WAIT);

	return 0;
}
