/*
 * Copyright (c) 2020 Manivannan Sadhasivam <mani@kernel.org>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/init.h>
#include <errno.h>
#include <zephyr/lorawan/lorawan.h>

#include "lw_priv.h"

#include <LoRaMac.h>
#include <Region.h>
#include "nvm/lorawan_nvm.h"

#ifdef CONFIG_LORAMAC_REGION_AS923
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_AS923
#elif CONFIG_LORAMAC_REGION_AU915
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_AU915
#elif CONFIG_LORAMAC_REGION_CN470
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_CN470
#elif CONFIG_LORAMAC_REGION_CN779
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_CN779
#elif CONFIG_LORAMAC_REGION_EU433
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_EU433
#elif CONFIG_LORAMAC_REGION_EU868
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_EU868
#elif CONFIG_LORAMAC_REGION_KR920
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_KR920
#elif CONFIG_LORAMAC_REGION_IN865
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_IN865
#elif CONFIG_LORAMAC_REGION_US915
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_US915
#elif CONFIG_LORAMAC_REGION_RU864
#define DEFAULT_LORAWAN_REGION LORAMAC_REGION_RU864
#else
#error "At least one LoRaWAN region should be selected"
#endif

/* Use version 1.0.3.0 for ABP */
#define LORAWAN_ABP_VERSION 0x01000300

#define LOG_LEVEL CONFIG_LORAWAN_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(lorawan);

K_SEM_DEFINE(mlme_confirm_sem, 0, 1);
K_SEM_DEFINE(mcps_confirm_sem, 0, 1);

K_MUTEX_DEFINE(lorawan_join_mutex);
K_MUTEX_DEFINE(lorawan_send_mutex);

/* We store both the default datarate requested through lorawan_set_datarate
 * and the current datarate so that we can use the default datarate for all
 * join requests, even as the current datarate changes due to ADR.
 */
static enum lorawan_datarate default_datarate;
static enum lorawan_datarate current_datarate;
static bool lorawan_adr_enable;

static sys_slist_t dl_callbacks;

static LoRaMacPrimitives_t mac_primitives;
static LoRaMacCallback_t mac_callbacks;

static LoRaMacEventInfoStatus_t last_mcps_confirm_status;
static LoRaMacEventInfoStatus_t last_mlme_confirm_status;
static LoRaMacEventInfoStatus_t last_mcps_indication_status;
static LoRaMacEventInfoStatus_t last_mlme_indication_status;

static LoRaMacRegion_t selected_region = DEFAULT_LORAWAN_REGION;

static uint8_t (*get_battery_level_user)(void);
static void (*dr_change_cb)(enum lorawan_datarate dr);

/* implementation required by the soft-se (software secure element) */
void BoardGetUniqueId(uint8_t *id)
{
	/* Do not change the default value */
}

static uint8_t get_battery_level(void)
{
	if (get_battery_level_user != NULL) {
		return get_battery_level_user();
	}

	return 255;
}

static void mac_process_notify(void)
{
	LoRaMacProcess();
}

static void datarate_observe(bool force_notification)
{
	MibRequestConfirm_t mib_req;

	mib_req.Type = MIB_CHANNELS_DATARATE;
	LoRaMacMibGetRequestConfirm(&mib_req);

	if ((mib_req.Param.ChannelsDatarate != current_datarate) ||
	    (force_notification)) {
		current_datarate = mib_req.Param.ChannelsDatarate;
		if (dr_change_cb) {
			dr_change_cb(current_datarate);
		}
		LOG_INF("Datarate changed: DR_%d", current_datarate);
	}
}

static void mcps_confirm_handler(McpsConfirm_t *mcps_confirm)
{
	LOG_DBG("Received McpsConfirm (for McpsRequest %d)",
		mcps_confirm->McpsRequest);

	if (mcps_confirm->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
		LOG_ERR("McpsRequest failed : %s",
			lorawan_eventinfo2str(mcps_confirm->Status));
	} else {
		LOG_DBG("McpsRequest success!");
	}

	/* Datarate may have changed due to a missed ADRACK */
	if (lorawan_adr_enable) {
		datarate_observe(false);
	}

	last_mcps_confirm_status = mcps_confirm->Status;
	k_sem_give(&mcps_confirm_sem);
}

static void mcps_indication_handler(McpsIndication_t *mcps_indication)
{
	struct lorawan_downlink_cb *cb;

	LOG_DBG("Received McpsIndication %d", mcps_indication->McpsIndication);

	if (mcps_indication->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
		LOG_ERR("McpsIndication failed : %s",
			lorawan_eventinfo2str(mcps_indication->Status));
		return;
	}

	/* Datarate can change as result of ADR command from server */
	if (lorawan_adr_enable) {
		datarate_observe(false);
	}

	/* Iterate over all registered downlink callbacks */
	SYS_SLIST_FOR_EACH_CONTAINER(&dl_callbacks, cb, node) {
		if ((cb->port == LW_RECV_PORT_ANY) ||
		    (cb->port == mcps_indication->Port)) {
			cb->cb(mcps_indication->Port,
			       /* IsUplinkTxPending also indicates pending downlinks */
			       mcps_indication->IsUplinkTxPending == 1,
			       mcps_indication->Rssi, mcps_indication->Snr,
			       mcps_indication->BufferSize,
			       mcps_indication->Buffer);
		}
	}

	last_mcps_indication_status = mcps_indication->Status;
}

static void mlme_confirm_handler(MlmeConfirm_t *mlme_confirm)
{
	MibRequestConfirm_t mib_req;

	LOG_DBG("Received MlmeConfirm (for MlmeRequest %d)",
		mlme_confirm->MlmeRequest);

	if (mlme_confirm->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
		LOG_ERR("MlmeConfirm failed : %s",
			lorawan_eventinfo2str(mlme_confirm->Status));
		goto out_sem;
	}

	switch (mlme_confirm->MlmeRequest) {
	case MLME_JOIN:
		mib_req.Type = MIB_DEV_ADDR;
		LoRaMacMibGetRequestConfirm(&mib_req);
		LOG_INF("Joined network! DevAddr: %08x", mib_req.Param.DevAddr);
		break;
	case MLME_LINK_CHECK:
		/* Not implemented */
		LOG_INF("Link check not implemented yet!");
		break;
	default:
		break;
	}

out_sem:
	last_mlme_confirm_status = mlme_confirm->Status;
	k_sem_give(&mlme_confirm_sem);
}

static void mlme_indication_handler(MlmeIndication_t *mlme_indication)
{
	LOG_DBG("Received MlmeIndication %d", mlme_indication->MlmeIndication);
	last_mlme_indication_status = mlme_indication->Status;
}

static LoRaMacStatus_t lorawan_join_otaa(
	const struct lorawan_join_config *join_cfg)
{
	MlmeReq_t mlme_req;
	MibRequestConfirm_t mib_req;

	mlme_req.Type = MLME_JOIN;
	mlme_req.Req.Join.Datarate = default_datarate;
	mlme_req.Req.Join.NetworkActivation = ACTIVATION_TYPE_OTAA;

	if (IS_ENABLED(CONFIG_LORAWAN_NVM_NONE)) {
		/* Retrieve the NVM context to store device nonce */
		mib_req.Type = MIB_NVM_CTXS;
		if (LoRaMacMibGetRequestConfirm(&mib_req) !=
			LORAMAC_STATUS_OK) {
			LOG_ERR("Could not get NVM context");
			return -EINVAL;
		}
		mib_req.Param.Contexts->Crypto.DevNonce =
			join_cfg->otaa.dev_nonce;
	}

	mib_req.Type = MIB_DEV_EUI;
	mib_req.Param.DevEui = join_cfg->dev_eui;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_JOIN_EUI;
	mib_req.Param.JoinEui = join_cfg->otaa.join_eui;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_NWK_KEY;
	mib_req.Param.NwkKey = join_cfg->otaa.nwk_key;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_APP_KEY;
	mib_req.Param.AppKey = join_cfg->otaa.app_key;
	LoRaMacMibSetRequestConfirm(&mib_req);

	return LoRaMacMlmeRequest(&mlme_req);
}

static LoRaMacStatus_t lorawan_join_abp(
	const struct lorawan_join_config *join_cfg)
{
	MibRequestConfirm_t mib_req;

	mib_req.Type = MIB_ABP_LORAWAN_VERSION;
	mib_req.Param.AbpLrWanVersion.Value = LORAWAN_ABP_VERSION;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_NET_ID;
	mib_req.Param.NetID = 0;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_DEV_ADDR;
	mib_req.Param.DevAddr = join_cfg->abp.dev_addr;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_F_NWK_S_INT_KEY;
	mib_req.Param.FNwkSIntKey = join_cfg->abp.nwk_skey;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_S_NWK_S_INT_KEY;
	mib_req.Param.SNwkSIntKey = join_cfg->abp.nwk_skey;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_NWK_S_ENC_KEY;
	mib_req.Param.NwkSEncKey = join_cfg->abp.nwk_skey;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_APP_S_KEY;
	mib_req.Param.AppSKey = join_cfg->abp.app_skey;
	LoRaMacMibSetRequestConfirm(&mib_req);

	mib_req.Type = MIB_NETWORK_ACTIVATION;
	mib_req.Param.NetworkActivation = ACTIVATION_TYPE_ABP;
	LoRaMacMibSetRequestConfirm(&mib_req);

	return LORAMAC_STATUS_OK;
}

int lorawan_set_region(enum lorawan_region region)
{
	switch (region) {

#if defined(CONFIG_LORAMAC_REGION_AS923)
	case LORAWAN_REGION_AS923:
		selected_region = LORAMAC_REGION_AS923;
		break;
#endif

#if defined(CONFIG_LORAMAC_REGION_AU915)
	case LORAWAN_REGION_AU915:
		selected_region = LORAMAC_REGION_AU915;
		break;
#endif

#if defined(CONFIG_LORAMAC_REGION_CN470)
	case LORAWAN_REGION_CN470:
		selected_region = LORAMAC_REGION_CN470;
		break;
#endif

#if defined(CONFIG_LORAMAC_REGION_CN779)
	case LORAWAN_REGION_CN779:
		selected_region = LORAMAC_REGION_CN779;
		break;
#endif

#if defined(CONFIG_LORAMAC_REGION_EU433)
	case LORAWAN_REGION_EU433:
		selected_region = LORAMAC_REGION_EU433;
		break;
#endif

#if defined(CONFIG_LORAMAC_REGION_EU868)
	case LORAWAN_REGION_EU868:
		selected_region = LORAMAC_REGION_EU868;
		break;
#endif

#if defined(CONFIG_LORAMAC_REGION_KR920)
	case LORAWAN_REGION_KR920:
		selected_region = LORAMAC_REGION_KR920;
		break;
#endif

#if defined(CONFIG_LORAMAC_REGION_IN865)
	case LORAWAN_REGION_IN865:
		selected_region = LORAMAC_REGION_IN865;
		break;
#endif

#if defined(CONFIG_LORAMAC_REGION_US915)
	case LORAWAN_REGION_US915:
		selected_region = LORAMAC_REGION_US915;
		break;
#endif

#if defined(CONFIG_LORAMAC_REGION_RU864)
	case LORAWAN_REGION_RU864:
		selected_region = LORAMAC_REGION_RU864;
		break;
#endif

	default:
		LOG_ERR("No support for region %d!", region);
		return -ENOTSUP;
	}

	LOG_DBG("Selected region %d", region);

	return 0;
}

int lorawan_join(const struct lorawan_join_config *join_cfg)
{
	MibRequestConfirm_t mib_req;
	LoRaMacStatus_t status;
	int ret = 0;

	k_mutex_lock(&lorawan_join_mutex, K_FOREVER);

	/* MIB_PUBLIC_NETWORK powers on the radio and does not turn it off */
	mib_req.Type = MIB_PUBLIC_NETWORK;
	mib_req.Param.EnablePublicNetwork = true;
	LoRaMacMibSetRequestConfirm(&mib_req);

	if (join_cfg->mode == LORAWAN_ACT_OTAA) {
		status = lorawan_join_otaa(join_cfg);
		if (status != LORAMAC_STATUS_OK) {
			LOG_ERR("OTAA join failed: %s",
				lorawan_status2str(status));
			ret = lorawan_status2errno(status);
			goto out;
		}

		LOG_DBG("Network join request sent!");

		/*
		 * We can be sure that the semaphore will be released for
		 * both success and failure cases after a specific time period.
		 * So we can use K_FOREVER and no need to check the return val.
		 */
		k_sem_take(&mlme_confirm_sem, K_FOREVER);
		if (last_mlme_confirm_status != LORAMAC_EVENT_INFO_STATUS_OK) {
			ret = lorawan_eventinfo2errno(last_mlme_confirm_status);
			goto out;
		}
	} else if (join_cfg->mode == LORAWAN_ACT_ABP) {
		status = lorawan_join_abp(join_cfg);
		if (status != LORAMAC_STATUS_OK) {
			LOG_ERR("ABP join failed: %s",
				lorawan_status2str(status));
			ret = lorawan_status2errno(status);
			goto out;
		}
	} else {
		ret = -EINVAL;
	}

out:
	/* If the join succeeded */
	if (ret == 0) {
		/*
		 * Several regions (AS923, AU915, US915) overwrite the
		 * datarate as part of the join process. Reset the datarate
		 * to the value requested (and validated) in
		 * lorawan_set_datarate so that the MAC layer is aware of the
		 * set datarate for LoRaMacQueryTxPossible. This is only
		 * performed when ADR is disabled as it the network servers
		 * responsibility to increase datarates when ADR is enabled.
		 */
		if (!lorawan_adr_enable) {
			MibRequestConfirm_t mib_req;

			mib_req.Type = MIB_CHANNELS_DATARATE;
			mib_req.Param.ChannelsDatarate = default_datarate;
			LoRaMacMibSetRequestConfirm(&mib_req);
		}

		/*
		 * Force a notification of the datarate on network join as the
		 * user may not have explicitly set a datarate to use.
		 */
		datarate_observe(true);
	}

	k_mutex_unlock(&lorawan_join_mutex);
	return ret;
}

int lorawan_set_class(enum lorawan_class dev_class)
{
	MibRequestConfirm_t mib_req;
	DeviceClass_t current_class;
	LoRaMacStatus_t status;

	mib_req.Type = MIB_DEVICE_CLASS;
	LoRaMacMibGetRequestConfirm(&mib_req);
	current_class = mib_req.Param.Class;

	switch (dev_class) {
	case LORAWAN_CLASS_A:
		mib_req.Param.Class = CLASS_A;
		break;
	case LORAWAN_CLASS_B:
		LOG_ERR("Class B not supported yet!");
		return -ENOTSUP;
	case LORAWAN_CLASS_C:
		mib_req.Param.Class = CLASS_C;
		break;
	default:
		return -EINVAL;
	}

	if (mib_req.Param.Class != current_class) {
		status = LoRaMacMibSetRequestConfirm(&mib_req);
		if (status != LORAMAC_STATUS_OK) {
			LOG_ERR("Failed to set device class: %s",
				lorawan_status2str(status));
			return lorawan_status2errno(status);
		}
	}

	return 0;
}

int lorawan_set_datarate(enum lorawan_datarate dr)
{
	MibRequestConfirm_t mib_req;

	/* Bail out if using ADR */
	if (lorawan_adr_enable) {
		return -EINVAL;
	}

	/* Notify MAC layer of the requested datarate */
	mib_req.Type = MIB_CHANNELS_DATARATE;
	mib_req.Param.ChannelsDatarate = dr;
	if (LoRaMacMibSetRequestConfirm(&mib_req) != LORAMAC_STATUS_OK) {
		/* Datarate is invalid for this region */
		return -EINVAL;
	}

	default_datarate = dr;
	current_datarate = dr;

	return 0;
}

void lorawan_get_payload_sizes(uint8_t *max_next_payload_size,
			       uint8_t *max_payload_size)
{
	LoRaMacTxInfo_t tx_info;

	/* QueryTxPossible cannot fail */
	(void) LoRaMacQueryTxPossible(0, &tx_info);

	*max_next_payload_size = tx_info.MaxPossibleApplicationDataSize;
	*max_payload_size = tx_info.CurrentPossiblePayloadSize;
}

enum lorawan_datarate lorawan_get_min_datarate(void)
{
	MibRequestConfirm_t mib_req;

	mib_req.Type = MIB_CHANNELS_MIN_TX_DATARATE;
	LoRaMacMibGetRequestConfirm(&mib_req);

	return mib_req.Param.ChannelsMinTxDatarate;
}

void lorawan_enable_adr(bool enable)
{
	MibRequestConfirm_t mib_req;

	if (enable != lorawan_adr_enable) {
		lorawan_adr_enable = enable;

		mib_req.Type = MIB_ADR;
		mib_req.Param.AdrEnable = lorawan_adr_enable;
		LoRaMacMibSetRequestConfirm(&mib_req);
	}
}

int lorawan_set_conf_msg_tries(uint8_t tries)
{
	MibRequestConfirm_t mib_req;

	mib_req.Type = MIB_CHANNELS_NB_TRANS;
	mib_req.Param.ChannelsNbTrans = tries;
	if (LoRaMacMibSetRequestConfirm(&mib_req) != LORAMAC_STATUS_OK) {
		return -EINVAL;
	}

	return 0;
}

int lorawan_send(uint8_t port, uint8_t *data, uint8_t len,
		 enum lorawan_message_type type)
{
	LoRaMacStatus_t status;
	McpsReq_t mcps_req;
	LoRaMacTxInfo_t tx_info;
	int ret = 0;
	bool empty_frame = false;

	if (data == NULL) {
		return -EINVAL;
	}

	k_mutex_lock(&lorawan_send_mutex, K_FOREVER);

	status = LoRaMacQueryTxPossible(len, &tx_info);
	if (status != LORAMAC_STATUS_OK) {
		/*
		 * If status indicates an error, then most likely the payload
		 * has exceeded the maximum possible length for the current
		 * region and datarate. We can't do much other than sending
		 * empty frame in order to flush MAC commands in stack and
		 * hoping the application to lower the payload size for
		 * next try.
		 */
		LOG_ERR("LoRaWAN Query Tx Possible Failed: %s",
			lorawan_status2str(status));
		empty_frame = true;
		mcps_req.Type = MCPS_UNCONFIRMED;
		mcps_req.Req.Unconfirmed.fBuffer = NULL;
		mcps_req.Req.Unconfirmed.fBufferSize = 0;
		mcps_req.Req.Unconfirmed.Datarate = DR_0;
	} else {
		switch (type) {
		case LORAWAN_MSG_UNCONFIRMED:
			mcps_req.Type = MCPS_UNCONFIRMED;
			break;
		case LORAWAN_MSG_CONFIRMED:
			mcps_req.Type = MCPS_CONFIRMED;
			break;
		}
		mcps_req.Req.Unconfirmed.fPort = port;
		mcps_req.Req.Unconfirmed.fBuffer = data;
		mcps_req.Req.Unconfirmed.fBufferSize = len;
		mcps_req.Req.Unconfirmed.Datarate = current_datarate;
	}

	status = LoRaMacMcpsRequest(&mcps_req);
	if (status != LORAMAC_STATUS_OK) {
		LOG_ERR("LoRaWAN Send failed: %s", lorawan_status2str(status));
		ret = lorawan_status2errno(status);
		goto out;
	}

	/*
	 * Always wait for MAC operations to complete.
	 * We can be sure that the semaphore will be released for
	 * both success and failure cases after a specific time period.
	 * So we can use K_FOREVER and no need to check the return val.
	 */
	k_sem_take(&mcps_confirm_sem, K_FOREVER);
	if (last_mcps_confirm_status != LORAMAC_EVENT_INFO_STATUS_OK) {
		ret = lorawan_eventinfo2errno(last_mcps_confirm_status);
	}

	/*
	 * Indicate to the application that the provided data was not sent and
	 * it has to resend the packet.
	 */
	if (empty_frame) {
		ret = -EAGAIN;
	}

out:
	k_mutex_unlock(&lorawan_send_mutex);
	return ret;
}

int lorawan_set_battery_level_callback(uint8_t (*battery_lvl_cb)(void))
{
	if (battery_lvl_cb == NULL) {
		return -EINVAL;
	}

	get_battery_level_user = battery_lvl_cb;

	return 0;
}

void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb)
{
	sys_slist_append(&dl_callbacks, &cb->node);
}

void lorawan_register_dr_changed_callback(void (*cb)(enum lorawan_datarate))
{
	dr_change_cb = cb;
}

int lorawan_start(void)
{
	LoRaMacStatus_t status;
	MibRequestConfirm_t mib_req;
	GetPhyParams_t phy_params;
	PhyParam_t phy_param;

	status = LoRaMacInitialization(&mac_primitives, &mac_callbacks,
				       selected_region);
	if (status != LORAMAC_STATUS_OK) {
		LOG_ERR("LoRaMacInitialization failed: %s",
			lorawan_status2str(status));
		return -EINVAL;
	}

	LOG_DBG("LoRaMAC Initialized");

	if (!IS_ENABLED(CONFIG_LORAWAN_NVM_NONE)) {
		lorawan_nvm_init();
		lorawan_nvm_data_restore();
	}

	status = LoRaMacStart();
	if (status != LORAMAC_STATUS_OK) {
		LOG_ERR("Failed to start the LoRaMAC stack: %s",
			lorawan_status2str(status));
		return -EINVAL;
	}

	/* Retrieve the default TX datarate for selected region */
	phy_params.Attribute = PHY_DEF_TX_DR;
	phy_param = RegionGetPhyParam(selected_region, &phy_params);
	default_datarate = phy_param.Value;
	current_datarate = default_datarate;

	/* TODO: Move these to a proper location */
	mib_req.Type = MIB_SYSTEM_MAX_RX_ERROR;
	mib_req.Param.SystemMaxRxError = CONFIG_LORAWAN_SYSTEM_MAX_RX_ERROR;
	LoRaMacMibSetRequestConfirm(&mib_req);

	return 0;
}

static int lorawan_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	sys_slist_init(&dl_callbacks);

	mac_primitives.MacMcpsConfirm = mcps_confirm_handler;
	mac_primitives.MacMcpsIndication = mcps_indication_handler;
	mac_primitives.MacMlmeConfirm = mlme_confirm_handler;
	mac_primitives.MacMlmeIndication = mlme_indication_handler;
	mac_callbacks.GetBatteryLevel = get_battery_level;
	mac_callbacks.GetTemperatureLevel = NULL;

	if (IS_ENABLED(CONFIG_LORAWAN_NVM_NONE)) {
		mac_callbacks.NvmDataChange = NULL;
	} else {
		mac_callbacks.NvmDataChange = lorawan_nvm_data_mgmt_event;
	}

	mac_callbacks.MacProcessNotify = mac_process_notify;

	return 0;
}

SYS_INIT(lorawan_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
