/*  Bluetooth Mesh */

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

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

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

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_MODEL)
#include "common/log.h"

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

#define HEALTH_TEST_STANDARD 0x00

/* Increasing this requires also increasing the system workqueue */
#define MAX_FAULTS 32
#define HEALTH_STATUS_SIZE_MAX (1 + 3 + MAX_FAULTS + 4)

#if BT_MESH_TX_SDU_MAX < HEALTH_STATUS_SIZE_MAX
#define HEALTH_STATUS_SIZE BT_MESH_TX_SDU_MAX
#else
#define HEALTH_STATUS_SIZE HEALTH_STATUS_SIZE_MAX
#endif

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

static void health_get_registered(struct bt_mesh_model *mod,
				  u16_t company_id,
				  struct net_buf_simple *msg)
{
	struct bt_mesh_health *srv = mod->user_data;
	u8_t fault_count;
	u8_t *test_id;
	int err;

	BT_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);
	fault_count = net_buf_simple_tailroom(msg) - 4;

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

static size_t health_get_current(struct bt_mesh_model *mod,
				 struct net_buf_simple *msg)
{
	struct bt_mesh_health *srv = mod->user_data;
	const struct bt_mesh_comp *comp;
	u8_t *test_id, *company_ptr;
	u16_t company_id;
	u8_t fault_count;
	int err;

	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();

	fault_count = net_buf_simple_tailroom(msg) - 4;

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

	return fault_count;
}

static void health_fault_get(struct bt_mesh_model *model,
			     struct bt_mesh_msg_ctx *ctx,
			     struct net_buf_simple *buf)
{
	struct net_buf_simple *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE);
	u16_t company_id;

	company_id = net_buf_simple_pull_le16(buf);

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

	health_get_registered(model, company_id, msg);

	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
		BT_ERR("Unable to send Health Current Status response");
	}
}

static void health_fault_clear_unrel(struct bt_mesh_model *model,
				     struct bt_mesh_msg_ctx *ctx,
				     struct net_buf_simple *buf)
{
	struct bt_mesh_health *srv = model->user_data;
	u16_t company_id;

	company_id = net_buf_simple_pull_le16(buf);

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

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

static void health_fault_clear(struct bt_mesh_model *model,
			       struct bt_mesh_msg_ctx *ctx,
			       struct net_buf_simple *buf)
{
	struct net_buf_simple *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE);
	struct bt_mesh_health *srv = model->user_data;
	u16_t company_id;

	company_id = net_buf_simple_pull_le16(buf);

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

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

	health_get_registered(model, company_id, msg);

	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
		BT_ERR("Unable to send Health Current Status response");
	}
}

static void health_fault_test_unrel(struct bt_mesh_model *model,
				    struct bt_mesh_msg_ctx *ctx,
				    struct net_buf_simple *buf)
{
	struct bt_mesh_health *srv = model->user_data;
	const struct bt_mesh_comp *comp;
	u16_t company_id;
	u8_t test_id;

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

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

	comp = bt_mesh_comp_get();
	if (comp->cid != company_id) {
		BT_WARN("CID 0x%04x doesn't match composition CID 0x%04x",
			company_id, comp->cid);
		return;
	}

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

static void health_fault_test(struct bt_mesh_model *model,
			      struct bt_mesh_msg_ctx *ctx,
			      struct net_buf_simple *buf)
{
	struct net_buf_simple *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE);
	struct bt_mesh_health *srv = model->user_data;
	u16_t company_id;
	u8_t test_id;

	BT_DBG("");

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

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

	if (srv->fault_test) {
		int err;

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

	health_get_registered(model, company_id, msg);

	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
		BT_ERR("Unable to send Health Current Status response");
	}
}

static void send_attention_status(struct bt_mesh_model *model,
				  struct bt_mesh_msg_ctx *ctx)
{
	/* Needed size: opcode (2 bytes) + msg + MIC */
	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4);
	struct bt_mesh_health *srv = model->user_data;
	u8_t time;

	time = k_delayed_work_remaining_get(&srv->attention.timer) / 1000;
	BT_DBG("%u second%s", time, (time == 1) ? "" : "s");

	bt_mesh_model_msg_init(msg, OP_ATTENTION_STATUS);

	net_buf_simple_add_u8(msg, time);

	bt_mesh_model_send(model, ctx, msg, NULL, NULL);
}

static void attention_get(struct bt_mesh_model *model,
			  struct bt_mesh_msg_ctx *ctx,
			  struct net_buf_simple *buf)
{
	BT_DBG("");

	send_attention_status(model, ctx);
}

static void attention_set_unrel(struct bt_mesh_model *model,
				struct bt_mesh_msg_ctx *ctx,
				struct net_buf_simple *buf)
{
	u8_t time;

	time = net_buf_simple_pull_u8(buf);

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

	bt_mesh_attention(model, time);
}

static void attention_set(struct bt_mesh_model *model,
			  struct bt_mesh_msg_ctx *ctx,
			  struct net_buf_simple *buf)
{
	BT_DBG("");

	attention_set_unrel(model, ctx, buf);

	send_attention_status(model, ctx);
}

static void send_health_period_status(struct bt_mesh_model *model,
				      struct bt_mesh_msg_ctx *ctx)
{
	/* Needed size: opcode (2 bytes) + msg + MIC */
	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4);

	bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_STATUS);

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

	bt_mesh_model_send(model, ctx, msg, NULL, NULL);
}

static void health_period_get(struct bt_mesh_model *model,
			      struct bt_mesh_msg_ctx *ctx,
			      struct net_buf_simple *buf)
{
	BT_DBG("");

	send_health_period_status(model, ctx);
}

static void health_period_set_unrel(struct bt_mesh_model *model,
				    struct bt_mesh_msg_ctx *ctx,
				    struct net_buf_simple *buf)
{
	u8_t period;

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

	BT_DBG("period %u", period);

	model->pub->period_div = period;
}

static void health_period_set(struct bt_mesh_model *model,
			      struct bt_mesh_msg_ctx *ctx,
			      struct net_buf_simple *buf)
{
	BT_DBG("");

	health_period_set_unrel(model, ctx, buf);

	send_health_period_status(model, ctx);
}

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

static void health_pub(struct bt_mesh_model *mod)
{
	struct net_buf_simple *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE);
	size_t count;
	int err;

	BT_DBG("");

	count = health_get_current(mod, msg);
	if (!count) {
		mod->pub->period_div = 0;
	}

	err = bt_mesh_model_publish(mod, msg);
	if (err) {
		BT_ERR("Publishing failed (err %d)", err);
	}
}

struct bt_mesh_model_pub bt_mesh_health_pub = {
	.func = health_pub,
};

int bt_mesh_fault_update(struct bt_mesh_elem *elem)
{
	struct bt_mesh_model *mod;

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

	k_delayed_work_submit(&mod->pub->timer, K_NO_WAIT);
	return 0;
}

static void attention_off(struct k_work *work)
{
	struct bt_mesh_health *srv = CONTAINER_OF(work, struct bt_mesh_health,
						  attention.timer.work);
	BT_DBG("");

	if (srv->attention.off) {
		srv->attention.off(srv->model);
	}
}

int bt_mesh_health_init(struct bt_mesh_model *model, bool primary)
{
	struct bt_mesh_health *srv = model->user_data;

	if (!srv) {
		if (!primary) {
			return 0;
		}

		BT_ERR("No Health Server context provided");
		return -EINVAL;
	}

	k_delayed_work_init(&srv->attention.timer, attention_off);

	srv->model = model;

	if (primary) {
		health_srv = srv;
	}

	return 0;
}

void bt_mesh_attention(struct bt_mesh_model *model, u8_t time)
{
	struct bt_mesh_health *srv;

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

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

	if (time) {
		if (srv->attention.on) {
			srv->attention.on(model);
		}

		k_delayed_work_submit(&srv->attention.timer, time * 1000);
	} else {
		k_delayed_work_cancel(&srv->attention.timer);

		if (srv->attention.off) {
			srv->attention.off(model);
		}
	}
}
