/*
 * Copyright (c) 2019 Foundries.io
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define LOG_MODULE_NAME net_lwm2m_obj_conn_mon
#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL

#include <logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

#include <string.h>
#include <init.h>
#include <net/net_if.h>
#include <net/net_ip.h>

#include "lwm2m_object.h"
#include "lwm2m_engine.h"

#define CONNMON_VERSION_MAJOR 1
#define CONNMON_VERSION_MINOR 0

/* Connectivity Monitoring resource IDs */
#define CONNMON_NETWORK_BEARER_ID		0
#define CONNMON_AVAIL_NETWORK_BEARER_ID		1
#define CONNMON_RADIO_SIGNAL_STRENGTH		2
#define CONNMON_LINK_QUALITY			3
#define CONNMON_IP_ADDRESSES			4
#define CONNMON_ROUTER_IP_ADDRESSES		5
#define CONNMON_LINK_UTILIZATION		6
#define CONNMON_APN				7
#define CONNMON_CELLID				8
#define CONNMON_SMNC				9
#define CONNMON_SMCC				10

#define CONNMON_MAX_ID				11

#define CONNMON_STRING_SHORT			8

#define CONNMON_AVAIL_BEARER_MAX	CONFIG_LWM2M_CONN_MON_BEARER_MAX
#define CONNMON_APN_MAX			CONFIG_LWM2M_CONN_MON_APN_MAX

#if defined(CONFIG_NET_IF_MAX_IPV6_COUNT) \
	&& defined(CONFIG_NET_IF_MAX_IPV4_COUNT)
#define CONNMON_IP_ADDRESS_MAX		(CONFIG_NET_IF_MAX_IPV6_COUNT + \
					CONFIG_NET_IF_MAX_IPV4_COUNT)
#elif defined(CONFIG_NET_IF_MAX_IPV6_COUNT)
#define CONNMON_IP_ADDRESS_MAX		CONFIG_NET_IF_MAX_IPV6_COUNT
#elif defined(CONFIG_NET_IF_MAX_IPV4_COUNT)
#define CONNMON_IP_ADDRESS_MAX		CONFIG_NET_IF_MAX_IPV4_COUNT
#else
#define CONNMON_IP_ADDRESS_MAX		1
#endif

#if defined(CONFIG_NET_MAX_ROUTERS)
#define CONNMON_ROUTER_IP_ADDRESS_MAX	CONFIG_NET_MAX_ROUTERS
#else
#define CONNMON_ROUTER_IP_ADDRESS_MAX	1
#endif

/*
 * Calculate resource instances as follows:
 * start with CONNMON_MAX_ID
 * subtract MULTI resources because their counts include 0 resource (4)
 * add CONNMON_AVAIL_BEARER_MAX resource instances
 * add CONNMON_APN_MAX resource instances
 * add CONNMON_IP_ADDRESS_MAX resource instances
 * add CONNMON_ROUTER_IP_ADDRESS_MAX resource instances
 */
#define RESOURCE_INSTANCE_COUNT        (CONNMON_MAX_ID - 4 + \
					CONNMON_AVAIL_BEARER_MAX + \
					CONNMON_APN_MAX + \
					CONNMON_IP_ADDRESS_MAX + \
					CONNMON_ROUTER_IP_ADDRESS_MAX)

/* resource state variables */
static int8_t net_bearer;
static int8_t rss;
static uint8_t link_quality;
static uint32_t cellid;
static uint16_t mnc;
static uint16_t mcc;

/* only 1 instance of Connection Monitoring object exists */
static struct lwm2m_engine_obj connmon;
static struct lwm2m_engine_obj_field fields[] = {
	OBJ_FIELD_DATA(CONNMON_NETWORK_BEARER_ID, R, U8),
	OBJ_FIELD_DATA(CONNMON_AVAIL_NETWORK_BEARER_ID, R, U8),
	OBJ_FIELD_DATA(CONNMON_RADIO_SIGNAL_STRENGTH, R, S8),
	OBJ_FIELD_DATA(CONNMON_LINK_QUALITY, R, U8),
	OBJ_FIELD_DATA(CONNMON_IP_ADDRESSES, R, STRING),
	OBJ_FIELD_DATA(CONNMON_ROUTER_IP_ADDRESSES, R_OPT, STRING),
	OBJ_FIELD_DATA(CONNMON_LINK_UTILIZATION, R_OPT, U8),
	OBJ_FIELD_DATA(CONNMON_APN, R_OPT, STRING),
	OBJ_FIELD_DATA(CONNMON_CELLID, R_OPT, U32),
	OBJ_FIELD_DATA(CONNMON_SMNC, R_OPT, U16),
	OBJ_FIELD_DATA(CONNMON_SMCC, R_OPT, U16)
};

static struct lwm2m_engine_obj_inst inst;
static struct lwm2m_engine_res res[CONNMON_MAX_ID];
static struct lwm2m_engine_res_inst res_inst[RESOURCE_INSTANCE_COUNT];

static struct lwm2m_engine_obj_inst *connmon_create(uint16_t obj_inst_id)
{
	int i = 0, j = 0;

	/* Set default values */
	net_bearer = 42U; /* Ethernet */
	rss = 0;
	link_quality = 0U;
	mnc = 0U;
	mcc = 0U;

	init_res_instance(res_inst, ARRAY_SIZE(res_inst));

	/* initialize instance resource data */
	INIT_OBJ_RES_DATA(CONNMON_NETWORK_BEARER_ID, res, i, res_inst, j,
			  &net_bearer, sizeof(net_bearer));
	INIT_OBJ_RES_MULTI_OPTDATA(CONNMON_AVAIL_NETWORK_BEARER_ID, res, i,
				   res_inst, j, CONNMON_AVAIL_BEARER_MAX,
				   false);
	INIT_OBJ_RES_DATA(CONNMON_RADIO_SIGNAL_STRENGTH, res, i, res_inst, j,
			  &rss, sizeof(rss));
	INIT_OBJ_RES_DATA(CONNMON_LINK_QUALITY, res, i, res_inst, j,
			  &link_quality, sizeof(link_quality));
	INIT_OBJ_RES_MULTI_OPTDATA(CONNMON_IP_ADDRESSES, res, i,
				   res_inst, j, CONNMON_IP_ADDRESS_MAX, false);
	INIT_OBJ_RES_MULTI_OPTDATA(CONNMON_ROUTER_IP_ADDRESSES, res, i,
				   res_inst, j, CONNMON_ROUTER_IP_ADDRESS_MAX,
				   false);
	INIT_OBJ_RES_MULTI_OPTDATA(CONNMON_APN, res, i, res_inst, j,
				   CONNMON_APN_MAX, false);
	INIT_OBJ_RES_DATA(CONNMON_CELLID, res, i, res_inst, j, &cellid,
			  sizeof(cellid));
	INIT_OBJ_RES_DATA(CONNMON_SMNC, res, i, res_inst, j, &mnc, sizeof(mnc));
	INIT_OBJ_RES_DATA(CONNMON_SMCC, res, i, res_inst, j, &mcc, sizeof(mcc));

	inst.resources = res;
	inst.resource_count = i;
	LOG_DBG("Create LWM2M connectivity monitoring instance: %d",
		obj_inst_id);
	return &inst;
}

static int lwm2m_connmon_init(const struct device *dev)
{
	struct lwm2m_engine_obj_inst *obj_inst = NULL;
	int ret = 0;

	/* initialize the Connection Monitoring field data */
	connmon.obj_id = LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID;
	connmon.version_major = CONNMON_VERSION_MAJOR;
	connmon.version_minor = CONNMON_VERSION_MINOR;
	connmon.is_core = true;
	connmon.fields = fields;
	connmon.field_count = ARRAY_SIZE(fields);
	connmon.max_instance_count = 1U;
	connmon.create_cb = connmon_create;
	lwm2m_register_obj(&connmon);

	/* auto create the only instance */
	ret = lwm2m_create_obj_inst(LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID,
				    0, &obj_inst);
	if (ret < 0) {
		LOG_DBG("Create LWM2M instance 0 error: %d", ret);
	}

	return ret;
}

SYS_INIT(lwm2m_connmon_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
