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

/*
 * Source material for IPSO Light Control object (3311):
 * https://github.com/IPSO-Alliance/pub/blob/master/docs/IPSO-Smart-Objects.pdf
 * Section: "16. IPSO Object: Light Control"
 */

#define LOG_MODULE_NAME net_ipso_light_control
#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL

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

#include <stdint.h>
#include <init.h>

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

#define LIGHT_VERSION_MAJOR 1
#define LIGHT_VERSION_MINOR 0

#define LIGHT_MAX_ID		8

#define MAX_INSTANCE_COUNT	CONFIG_LWM2M_IPSO_LIGHT_CONTROL_INSTANCE_COUNT

#define LIGHT_STRING_SHORT	8
#define LIGHT_STRING_LONG       64

/*
 * Calculate resource instances as follows:
 * start with LIGHT_MAX_ID
 */
#define RESOURCE_INSTANCE_COUNT	(LIGHT_MAX_ID)

/* resource state variables */
static bool on_off_value[MAX_INSTANCE_COUNT];
static uint8_t dimmer_value[MAX_INSTANCE_COUNT];
static int32_t on_time_value[MAX_INSTANCE_COUNT];
static uint32_t on_time_offset[MAX_INSTANCE_COUNT];
static float32_value_t cumulative_active_value[MAX_INSTANCE_COUNT];
static float32_value_t power_factor_value[MAX_INSTANCE_COUNT];
static char colour[MAX_INSTANCE_COUNT][LIGHT_STRING_LONG];
static char units[MAX_INSTANCE_COUNT][LIGHT_STRING_SHORT];

static struct lwm2m_engine_obj light_control;
static struct lwm2m_engine_obj_field fields[] = {
	OBJ_FIELD_DATA(ON_OFF_RID, RW, BOOL),
	OBJ_FIELD_DATA(DIMMER_RID, RW_OPT, U8),
	OBJ_FIELD_DATA(ON_TIME_RID, RW_OPT, S32),
	OBJ_FIELD_DATA(CUMULATIVE_ACTIVE_POWER_RID, R_OPT, FLOAT),
	OBJ_FIELD_DATA(POWER_FACTOR_RID, R_OPT, FLOAT),
	OBJ_FIELD_DATA(COLOUR_RID, RW_OPT, STRING),
	OBJ_FIELD_DATA(SENSOR_UNITS_RID, R_OPT, STRING),
	OBJ_FIELD_DATA(APPLICATION_TYPE_RID, RW_OPT, STRING),
};

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

static void *on_time_read_cb(uint16_t obj_inst_id, uint16_t res_id, uint16_t res_inst_id,
			     size_t *data_len)
{
	int i;

	for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
		if (!inst[i].obj || inst[i].obj_inst_id != obj_inst_id) {
			continue;
		}

		if (on_off_value[i]) {
			on_time_value[i] = (k_uptime_get() / MSEC_PER_SEC) -
				on_time_offset[i];
		}

		*data_len = sizeof(on_time_value[i]);
		return &on_time_value[i];
	}

	return NULL;
}

static int on_time_post_write_cb(uint16_t obj_inst_id,
				 uint16_t res_id, uint16_t res_inst_id,
				 uint8_t *data, uint16_t data_len,
				 bool last_block, size_t total_size)
{
	int i;

	if (data_len != 4U) {
		LOG_ERR("unknown size %u", data_len);
		return -EINVAL;
	}

	int32_t counter = *(int32_t *) data;

	for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
		if (!inst[i].obj || inst[i].obj_inst_id != obj_inst_id) {
			continue;
		}

		if (counter == 0) {
			on_time_offset[i] =
				(int32_t)(k_uptime_get() / MSEC_PER_SEC);
		}

		return 0;
	}

	return -ENOENT;
}

static struct lwm2m_engine_obj_inst *light_control_create(uint16_t obj_inst_id)
{
	int index, avail = -1, i = 0, j = 0;

	/* Check that there is no other instance with this ID */
	for (index = 0; index < MAX_INSTANCE_COUNT; index++) {
		if (inst[index].obj && inst[index].obj_inst_id == obj_inst_id) {
			LOG_ERR("Can not create instance - "
				"already existing: %u", obj_inst_id);
			return NULL;
		}

		/* Save first available slot index */
		if (avail < 0 && !inst[index].obj) {
			avail = index;
		}
	}

	if (avail < 0) {
		LOG_ERR("Can not create instance - no more room: %u",
			obj_inst_id);
		return NULL;
	}

	/* Set default values */
	on_off_value[avail] = false;
	dimmer_value[avail] = 0U;
	on_time_value[avail] = 0;
	on_time_offset[avail] = 0U;
	cumulative_active_value[avail].val1 = 0;
	cumulative_active_value[avail].val2 = 0;
	power_factor_value[avail].val1 = 0;
	power_factor_value[avail].val2 = 0;
	colour[avail][0] = '\0';
	units[avail][0] = '\0';

	(void)memset(res[avail], 0,
		     sizeof(res[avail][0]) * ARRAY_SIZE(res[avail]));
	init_res_instance(res_inst[avail], ARRAY_SIZE(res_inst[avail]));

	/* initialize instance resource data */
	INIT_OBJ_RES_DATA(ON_OFF_RID, res[avail], i, res_inst[avail], j,
			  &on_off_value[avail], sizeof(*on_off_value));
	INIT_OBJ_RES_DATA(DIMMER_RID, res[avail], i, res_inst[avail], j,
			  &dimmer_value[avail], sizeof(*dimmer_value));
	INIT_OBJ_RES(ON_TIME_RID, res[avail], i, res_inst[avail], j, 1, false,
		     true, &on_time_value[avail], sizeof(*on_time_value),
		     on_time_read_cb, NULL, NULL, on_time_post_write_cb, NULL);
	INIT_OBJ_RES_DATA(CUMULATIVE_ACTIVE_POWER_RID, res[avail], i,
			  res_inst[avail], j, &cumulative_active_value[avail],
			  sizeof(*cumulative_active_value));
	INIT_OBJ_RES_DATA(POWER_FACTOR_RID, res[avail], i, res_inst[avail], j,
			  &power_factor_value[avail],
			  sizeof(*power_factor_value));
	INIT_OBJ_RES_DATA(COLOUR_RID, res[avail], i, res_inst[avail], j,
			  colour[avail], LIGHT_STRING_LONG);
	INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[avail], i, res_inst[avail], j,
			  units[avail], LIGHT_STRING_SHORT);
	INIT_OBJ_RES_OPTDATA(APPLICATION_TYPE_RID, res[avail], i,
			     res_inst[avail], j);

	inst[avail].resources = res[avail];
	inst[avail].resource_count = i;

	LOG_DBG("Create IPSO Light Control instance: %d", obj_inst_id);

	return &inst[avail];
}

static int ipso_light_control_init(const struct device *dev)
{
	light_control.obj_id = IPSO_OBJECT_LIGHT_CONTROL_ID;
	light_control.version_major = LIGHT_VERSION_MAJOR;
	light_control.version_minor = LIGHT_VERSION_MINOR;
	light_control.is_core = false;
	light_control.fields = fields;
	light_control.field_count = ARRAY_SIZE(fields);
	light_control.max_instance_count = MAX_INSTANCE_COUNT;
	light_control.create_cb = light_control_create;
	lwm2m_register_obj(&light_control);

	return 0;
}

SYS_INIT(ipso_light_control_init, APPLICATION,
	 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
