/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2018  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <ell/ell.h>

#include "lib/bluetooth.h"
#include "lib/hci.h"

#include "mesh/mesh-defs.h"

#include "mesh/mesh-io.h"
#include "mesh/mesh-io-api.h"

/* List of Mesh-IO Type headers */
#include "mesh/mesh-io-generic.h"

/* List of Supported Mesh-IO Types */
static const struct mesh_io_table table[] = {
	{MESH_IO_TYPE_GENERIC,	&mesh_io_generic}
};

static struct l_queue *io_list;

static bool match_by_io(const void *a, const void *b)
{
	return a == b;
}

static bool match_by_index(const void *a, const void *b)
{
	const struct mesh_io *io = a;

	return io->index == L_PTR_TO_UINT(b);
}

struct mesh_io *mesh_io_new(uint16_t index, enum mesh_io_type type)
{
	const struct mesh_io_api *api = NULL;
	struct mesh_io *io;
	uint16_t i;

	l_info("%s %d\n", __func__, type);

	for (i = 0; i < L_ARRAY_SIZE(table); i++) {
		if (table[i].type == type) {
			api = table[i].api;
			break;
		}
	}

	io = l_queue_find(io_list, match_by_index, L_UINT_TO_PTR(index));

	if (!api || !api->init || io)
		return NULL;

	io = l_new(struct mesh_io, 1);

	if (!io)
		return NULL;

	io->type = type;
	io->index = index;
	io->api = api;
	if (!api->init(index, io))
		goto fail;

	if (!io_list)
		io_list = l_queue_new();

	if (api->set) {
		uint8_t pkt = MESH_AD_TYPE_NETWORK;
		uint8_t bec = MESH_AD_TYPE_BEACON;
		uint8_t prv = MESH_AD_TYPE_PROVISION;

		api->set(io, 1, &bec, 1, NULL, NULL);
		api->set(io, 2, &prv, 1, NULL, NULL);
		api->set(io, 3, &pkt, 1, NULL, NULL);
	}

	if (l_queue_push_head(io_list, io))
		return io;

fail:
	if (api->destroy)
		api->destroy(io);

	l_free(io);
	return NULL;
}

void mesh_io_destroy(struct mesh_io *io)
{
	io = l_queue_remove_if(io_list, match_by_io, io);

	if (io && io->api && io->api->destroy)
		io->api->destroy(io);

	l_free(io);

	if (l_queue_isempty(io_list)) {
		l_queue_destroy(io_list, NULL);
		io_list = NULL;
	}
}

bool mesh_io_get_caps(struct mesh_io *io, struct mesh_io_caps *caps)
{
	io = l_queue_find(io_list, match_by_io, io);

	if (io && io->api && io->api->caps)
		return io->api->caps(io, caps);

	return false;
}

bool mesh_io_register_recv_cb(struct mesh_io *io, uint8_t filter_id,
				mesh_io_recv_func_t cb, void *user_data)
{
	io = l_queue_find(io_list, match_by_io, io);

	if (io && io->api && io->api->reg)
		return io->api->reg(io, filter_id, cb, user_data);

	return false;
}

bool mesh_io_deregister_recv_cb(struct mesh_io *io, uint8_t filter_id)
{
	io = l_queue_find(io_list, match_by_io, io);

	if (io && io->api && io->api->dereg)
		return io->api->dereg(io, filter_id);

	return false;
}

bool mesh_set_filter(struct mesh_io *io, uint8_t filter_id,
				const uint8_t *data, uint8_t len,
				mesh_io_status_func_t cb, void *user_data)
{
	io = l_queue_find(io_list, match_by_io, io);

	if (io && io->api && io->api->set)
		return io->api->set(io, filter_id, data, len, cb, user_data);

	return false;
}

bool mesh_io_send(struct mesh_io *io, struct mesh_io_send_info *info,
					const uint8_t *data, uint16_t len)
{
	io = l_queue_find(io_list, match_by_io, io);

	if (io && io->api && io->api->send)
		return io->api->send(io, info, data, len);

	return false;
}

bool mesh_io_send_cancel(struct mesh_io *io, uint8_t *pattern, uint8_t len)
{
	io = l_queue_find(io_list, match_by_io, io);

	if (io && io->api && io->api->cancel)
		return io->api->cancel(io, pattern, len);

	return false;
}
