/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/net/buf.h>
#include <zephyr/sys/byteorder.h>
#include <string.h>

#include <zephyr/bluetooth/mesh.h>
#include "crypto.h"
#include "access.h"

int bt_mesh_dfu_metadata_decode(struct net_buf_simple *buf,
				struct bt_mesh_dfu_metadata *metadata)
{
	if (buf->len < 12) {
		return -EMSGSIZE;
	}

	metadata->fw_ver.major = net_buf_simple_pull_u8(buf);
	metadata->fw_ver.minor = net_buf_simple_pull_u8(buf);
	metadata->fw_ver.revision = net_buf_simple_pull_le16(buf);
	metadata->fw_ver.build_num = net_buf_simple_pull_le32(buf);
	metadata->fw_size = net_buf_simple_pull_le24(buf);
	metadata->fw_core_type = net_buf_simple_pull_u8(buf);

	if (metadata->fw_core_type & BT_MESH_DFU_FW_CORE_TYPE_APP) {
		if (buf->len < 6) {
			return -EMSGSIZE;
		}

		metadata->comp_hash = net_buf_simple_pull_le32(buf);
		metadata->elems = net_buf_simple_pull_le16(buf);
	}

	metadata->user_data = buf->len > 0 ? buf->data : NULL;
	metadata->user_data_len = buf->len;

	return 0;
}


int bt_mesh_dfu_metadata_encode(const struct bt_mesh_dfu_metadata *metadata,
				struct net_buf_simple *buf)
{
	size_t md_len_min = 12 + metadata->user_data_len;

	if (metadata->fw_core_type & BT_MESH_DFU_FW_CORE_TYPE_APP) {
		md_len_min += 6;
	}

	if (net_buf_simple_tailroom(buf) < md_len_min) {
		return -EMSGSIZE;
	}

	net_buf_simple_add_u8(buf, metadata->fw_ver.major);
	net_buf_simple_add_u8(buf, metadata->fw_ver.minor);
	net_buf_simple_add_le16(buf, metadata->fw_ver.revision);
	net_buf_simple_add_le32(buf, metadata->fw_ver.build_num);
	net_buf_simple_add_le24(buf, metadata->fw_size);
	net_buf_simple_add_u8(buf, metadata->fw_core_type);
	net_buf_simple_add_le32(buf, metadata->comp_hash);
	net_buf_simple_add_le16(buf, metadata->elems);

	if (metadata->user_data_len > 0) {
		net_buf_simple_add_mem(buf, metadata->user_data, metadata->user_data_len);
	}

	return 0;
}

int bt_mesh_dfu_metadata_comp_hash_get(struct net_buf_simple *buf, uint8_t *key, uint32_t *hash)
{
	uint8_t mac[16];
	int err;
	struct bt_mesh_sg sg = {.data = buf->data, .len = buf->len};

	err = bt_mesh_aes_cmac(key, &sg, 1, mac);
	if (err) {
		return err;
	}

	*hash = sys_get_le32(mac);

	return 0;
}

int bt_mesh_dfu_metadata_comp_hash_local_get(uint8_t *key, uint32_t *hash)
{
	NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX);
	int err;

	err = bt_mesh_comp_data_get_page_0(&buf, 0);
	if (err) {
		return err;
	}

	err = bt_mesh_dfu_metadata_comp_hash_get(&buf, key, hash);
	return err;
}
