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

#include <zephyr/kernel.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include <zephyr/types.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/util.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/mesh.h>

#include "mesh.h"
#include "net.h"
#include "transport.h"
#include "access.h"
#include "foundation.h"

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

#define HEALTH_TEST_STANDARD 0x00

/* Health Server context of the primary element */
struct bt_mesh_health_srv *health_srv;

static void health_get_registered(const struct bt_mesh_model *mod,
				  uint16_t company_id,
				  struct net_buf_simple *msg)
{
	struct bt_mesh_health_srv *srv = mod->rt->user_data;
	uint8_t *test_id;

	LOG_DBG("Company ID 0x%04x", company_id);

	bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_STATUS);

	test_id = net_buf_simple_add(msg, 1);
	net_buf_simple_add_le16(msg, company_id);

	if (srv->cb && srv->cb->fault_get_reg) {
		uint8_t fault_count = net_buf_simple_tailroom(msg) - 4;
		int err;

		err = srv->cb->fault_get_reg(mod, company_id, test_id,
					     net_buf_simple_tail(msg),
					     &fault_count);
		if (err) {
			LOG_ERR("Failed to get faults (err %d)", err);
			*test_id = HEALTH_TEST_STANDARD;
		} else {
			net_buf_simple_add(msg, fault_count);
		}
	} else {
		LOG_WRN("No callback for getting faults");
		*test_id = HEALTH_TEST_STANDARD;
	}
}

static size_t health_get_current(const struct bt_mesh_model *mod,
				 struct net_buf_simple *msg)
{
	struct bt_mesh_health_srv *srv = mod->rt->user_data;
	const struct bt_mesh_comp *comp;
	uint8_t *test_id, *company_ptr;
	uint16_t company_id;
	uint8_t fault_count;

	bt_mesh_model_msg_init(msg, OP_HEALTH_CURRENT_STATUS);

	test_id = net_buf_simple_add(msg, 1);
	company_ptr = net_buf_simple_add(msg, sizeof(company_id));
	comp = bt_mesh_comp_get();

	if (srv->cb && srv->cb->fault_get_cur) {
		fault_count = net_buf_simple_tailroom(msg);
		int err;

		err = srv->cb->fault_get_cur(mod, test_id, &company_id,
					     net_buf_simple_tail(msg),
					     &fault_count);
		if (err) {
			LOG_ERR("Failed to get faults (err %d)", err);
			sys_put_le16(comp->cid, company_ptr);
			*test_id = HEALTH_TEST_STANDARD;
			fault_count = 0U;
		} else {
			sys_put_le16(company_id, company_ptr);
			net_buf_simple_add(msg, fault_count);
		}
	} else {
		LOG_WRN("No callback for getting faults");
		sys_put_le16(comp->cid, company_ptr);
		*test_id = HEALTH_TEST_STANDARD;
		fault_count = 0U;
	}

	return fault_count;
}

static int health_fault_get(const struct bt_mesh_model *model,
			    struct bt_mesh_msg_ctx *ctx,
			    struct net_buf_simple *buf)
{
	NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX);
	uint16_t company_id;

	company_id = net_buf_simple_pull_le16(buf);

	LOG_DBG("company_id 0x%04x", company_id);

	health_get_registered(model, company_id, &sdu);

	if (bt_mesh_model_send(model, ctx, &sdu, NULL, NULL)) {
		LOG_ERR("Unable to send Health Current Status response");
	}

	return 0;
}

static int health_fault_clear_unrel(const struct bt_mesh_model *model,
				    struct bt_mesh_msg_ctx *ctx,
				    struct net_buf_simple *buf)
{
	struct bt_mesh_health_srv *srv = model->rt->user_data;
	uint16_t company_id;

	company_id = net_buf_simple_pull_le16(buf);

	LOG_DBG("company_id 0x%04x", company_id);

	if (srv->cb && srv->cb->fault_clear) {
		return srv->cb->fault_clear(model, company_id);
	}

	return 0;
}

static int health_fault_clear(const struct bt_mesh_model *model,
			      struct bt_mesh_msg_ctx *ctx,
			      struct net_buf_simple *buf)
{
	NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX);
	struct bt_mesh_health_srv *srv = model->rt->user_data;
	uint16_t company_id;

	company_id = net_buf_simple_pull_le16(buf);

	LOG_DBG("company_id 0x%04x", company_id);

	if (srv->cb && srv->cb->fault_clear) {
		int err;

		err = srv->cb->fault_clear(model, company_id);
		if (err) {
			return err;
		}
	}

	health_get_registered(model, company_id, &sdu);

	if (bt_mesh_model_send(model, ctx, &sdu, NULL, NULL)) {
		LOG_ERR("Unable to send Health Current Status response");
	}

	return 0;
}

static int health_fault_test_unrel(const struct bt_mesh_model *model,
				    struct bt_mesh_msg_ctx *ctx,
				    struct net_buf_simple *buf)
{
	struct bt_mesh_health_srv *srv = model->rt->user_data;
	uint16_t company_id;
	uint8_t test_id;

	test_id = net_buf_simple_pull_u8(buf);
	company_id = net_buf_simple_pull_le16(buf);

	LOG_DBG("test 0x%02x company 0x%04x", test_id, company_id);

	if (srv->cb && srv->cb->fault_test) {
		return srv->cb->fault_test(model, test_id, company_id);
	}

	return 0;
}

static int health_fault_test(const struct bt_mesh_model *model,
			     struct bt_mesh_msg_ctx *ctx,
			     struct net_buf_simple *buf)
{
	NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX);
	struct bt_mesh_health_srv *srv = model->rt->user_data;
	uint16_t company_id;
	uint8_t test_id;

	LOG_DBG("");

	test_id = net_buf_simple_pull_u8(buf);
	company_id = net_buf_simple_pull_le16(buf);

	LOG_DBG("test 0x%02x company 0x%04x", test_id, company_id);

	if (srv->cb && srv->cb->fault_test) {
		int err;

		err = srv->cb->fault_test(model, test_id, company_id);
		if (err) {
			LOG_WRN("Running fault test failed with err %d", err);
			return err;
		}
	}

	health_get_registered(model, company_id, &sdu);

	if (bt_mesh_model_send(model, ctx, &sdu, NULL, NULL)) {
		LOG_ERR("Unable to send Health Current Status response");
	}

	return 0;
}

static int send_attention_status(const struct bt_mesh_model *model,
				 struct bt_mesh_msg_ctx *ctx)
{
	/* Needed size: opcode (2 bytes) + msg + MIC */
	BT_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_STATUS, 1);
	struct bt_mesh_health_srv *srv = model->rt->user_data;
	uint8_t time;

	time = k_ticks_to_ms_floor32(
		k_work_delayable_remaining_get(&srv->attn_timer)) / 1000U;
	LOG_DBG("%u second%s", time, (time == 1U) ? "" : "s");

	bt_mesh_model_msg_init(&msg, OP_ATTENTION_STATUS);

	net_buf_simple_add_u8(&msg, time);

	if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
		LOG_ERR("Unable to send Attention Status");
	}

	return 0;
}

static int attention_get(const struct bt_mesh_model *model,
			 struct bt_mesh_msg_ctx *ctx,
			 struct net_buf_simple *buf)
{
	LOG_DBG("");

	return send_attention_status(model, ctx);
}

static int attention_set_unrel(const struct bt_mesh_model *model,
			       struct bt_mesh_msg_ctx *ctx,
			       struct net_buf_simple *buf)
{
	uint8_t time;

	time = net_buf_simple_pull_u8(buf);

	LOG_DBG("%u second%s", time, (time == 1U) ? "" : "s");

	bt_mesh_attention(model, time);

	return 0;
}

static int attention_set(const struct bt_mesh_model *model,
			 struct bt_mesh_msg_ctx *ctx,
			 struct net_buf_simple *buf)
{
	int err;

	LOG_DBG("");

	err = attention_set_unrel(model, ctx, buf);
	if (err) {
		return err;
	}

	return send_attention_status(model, ctx);
}

static int send_health_period_status(const struct bt_mesh_model *model,
				     struct bt_mesh_msg_ctx *ctx)
{
	/* Needed size: opcode (2 bytes) + msg + MIC */
	BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_STATUS, 1);

	bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_STATUS);

	net_buf_simple_add_u8(&msg, model->pub->period_div);

	if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
		LOG_ERR("Unable to send Health Period Status");
	}

	return 0;
}

static int health_period_get(const struct bt_mesh_model *model,
			      struct bt_mesh_msg_ctx *ctx,
			      struct net_buf_simple *buf)
{
	LOG_DBG("");

	return send_health_period_status(model, ctx);
}

static int health_period_set_unrel(const struct bt_mesh_model *model,
				    struct bt_mesh_msg_ctx *ctx,
				    struct net_buf_simple *buf)
{
	uint8_t period;

	period = net_buf_simple_pull_u8(buf);
	if (period > 15) {
		LOG_WRN("Prohibited period value %u", period);
		return -EINVAL;
	}

	LOG_DBG("period %u", period);

	model->pub->period_div = period;

	return 0;
}

static int health_period_set(const struct bt_mesh_model *model,
			     struct bt_mesh_msg_ctx *ctx,
			     struct net_buf_simple *buf)
{
	int err;

	LOG_DBG("");

	err = health_period_set_unrel(model, ctx, buf);
	if (err) {
		return err;
	}

	return send_health_period_status(model, ctx);
}

const struct bt_mesh_model_op bt_mesh_health_srv_op[] = {
	{ OP_HEALTH_FAULT_GET,         BT_MESH_LEN_EXACT(2),   health_fault_get },
	{ OP_HEALTH_FAULT_CLEAR,       BT_MESH_LEN_EXACT(2),   health_fault_clear },
	{ OP_HEALTH_FAULT_CLEAR_UNREL, BT_MESH_LEN_EXACT(2),   health_fault_clear_unrel },
	{ OP_HEALTH_FAULT_TEST,        BT_MESH_LEN_EXACT(3),   health_fault_test },
	{ OP_HEALTH_FAULT_TEST_UNREL,  BT_MESH_LEN_EXACT(3),   health_fault_test_unrel },
	{ OP_HEALTH_PERIOD_GET,        BT_MESH_LEN_EXACT(0),   health_period_get },
	{ OP_HEALTH_PERIOD_SET,        BT_MESH_LEN_EXACT(1),   health_period_set },
	{ OP_HEALTH_PERIOD_SET_UNREL,  BT_MESH_LEN_EXACT(1),   health_period_set_unrel },
	{ OP_ATTENTION_GET,            BT_MESH_LEN_EXACT(0),   attention_get },
	{ OP_ATTENTION_SET,            BT_MESH_LEN_EXACT(1),   attention_set },
	{ OP_ATTENTION_SET_UNREL,      BT_MESH_LEN_EXACT(1),   attention_set_unrel },
	BT_MESH_MODEL_OP_END,
};

static int health_pub_update(const struct bt_mesh_model *mod)
{
	struct bt_mesh_model_pub *pub = mod->pub;
	size_t count;

	LOG_DBG("");

	count = health_get_current(mod, pub->msg);
	if (count) {
		pub->fast_period = 1U;
	} else {
		pub->fast_period = 0U;
	}

	return 0;
}

int bt_mesh_health_srv_fault_update(const struct bt_mesh_elem *elem)
{
	const struct bt_mesh_model *mod;

	mod = bt_mesh_model_find(elem, BT_MESH_MODEL_ID_HEALTH_SRV);
	if (!mod) {
		return -EINVAL;
	}

	/* Let periodic publishing, if enabled, take care of sending the
	 * Health Current Status.
	 */
	if (bt_mesh_model_pub_period_get(mod) > 0) {
		return 0;
	}

	health_pub_update(mod);

	return bt_mesh_model_publish(mod);
}

static void attention_off(struct k_work *work)
{
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct bt_mesh_health_srv *srv = CONTAINER_OF(dwork,
						      struct bt_mesh_health_srv,
						      attn_timer);
	LOG_DBG("");

	if (srv->cb && srv->cb->attn_off) {
		srv->cb->attn_off(srv->model);
	}
}

static int health_srv_init(const struct bt_mesh_model *model)
{
	struct bt_mesh_health_srv *srv = model->rt->user_data;

	if (!srv) {
		LOG_ERR("No Health Server context provided");
		return -EINVAL;
	}

	if (!model->pub) {
		LOG_ERR("Health Server has no publication support");
		return -EINVAL;
	}

	model->pub->update = health_pub_update;

	k_work_init_delayable(&srv->attn_timer, attention_off);

	srv->model = model;

	if (bt_mesh_model_in_primary(model)) {
		health_srv = srv;
	}

	return 0;
}

const struct bt_mesh_model_cb bt_mesh_health_srv_cb = {
	.init = health_srv_init,
};

void bt_mesh_attention(const struct bt_mesh_model *model, uint8_t time)
{
	struct bt_mesh_health_srv *srv;

	if (!model) {
		srv = health_srv;
		if (!srv) {
			LOG_WRN("No Health Server available");
			return;
		}

		model = srv->model;
	} else {
		srv = model->rt->user_data;
	}

	if ((time > 0) && srv->cb && srv->cb->attn_on) {
		srv->cb->attn_on(model);
	}

	k_work_reschedule(&srv->attn_timer, K_SECONDS(time));
}
