/*
 * Copyright (C) 2013 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>

#include "hal-log.h"
#include "hal.h"
#include "hal-msg.h"
#include "hal-ipc.h"

static const bthh_callbacks_t *cbacks;

static bool interface_ready(void)
{
	return cbacks != NULL;
}

static void handle_conn_state(void *buf, uint16_t len)
{
	struct hal_ev_hidhost_conn_state *ev = buf;

	if (cbacks->connection_state_cb)
		cbacks->connection_state_cb((bt_bdaddr_t *) ev->bdaddr,
								ev->state);
}

static void handle_info(void *buf, uint16_t len)
{
	struct hal_ev_hidhost_info *ev = buf;
	bthh_hid_info_t info;

	info.attr_mask = ev->attr;
	info.sub_class = ev->subclass;
	info.app_id = ev->app_id;
	info.vendor_id = ev->vendor;
	info.product_id = ev->product;
	info.version = ev->version;
	info.ctry_code = ev->country;
	info.dl_len = ev->descr_len;
	memcpy(info.dsc_list, ev->descr, info.dl_len);

	if (cbacks->hid_info_cb)
		cbacks->hid_info_cb((bt_bdaddr_t *) ev->bdaddr, info);
}

static void handle_proto_mode(void *buf, uint16_t len)
{
	struct hal_ev_hidhost_proto_mode *ev = buf;

	if (cbacks->protocol_mode_cb)
		cbacks->protocol_mode_cb((bt_bdaddr_t *) ev->bdaddr,
							ev->status, ev->mode);
}

static void handle_get_report(void *buf, uint16_t len)
{
	struct hal_ev_hidhost_get_report *ev = buf;

	if (len != sizeof(*ev) + ev->len) {
		error("invalid get report event, aborting");
		exit(EXIT_FAILURE);
	}

	if (cbacks->get_report_cb)
		cbacks->get_report_cb((bt_bdaddr_t *) ev->bdaddr, ev->status,
							ev->data, ev->len);
}

static void handle_virtual_unplug(void *buf, uint16_t len)
{
	struct hal_ev_hidhost_virtual_unplug *ev = buf;

	if (cbacks->virtual_unplug_cb)
		cbacks->virtual_unplug_cb((bt_bdaddr_t *) ev->bdaddr,
								ev->status);
}

/* handlers will be called from notification thread context,
 * index in table equals to 'opcode - HAL_MINIMUM_EVENT' */
static const struct hal_ipc_handler ev_handlers[] = {
	{	/* HAL_EV_HIDHOST_CONN_STATE */
		.handler = handle_conn_state,
		.var_len = false,
		.data_len = sizeof(struct hal_ev_hidhost_conn_state)
	},
	{	/* HAL_EV_HIDHOST_INFO */
		.handler = handle_info,
		.var_len = false,
		.data_len = sizeof(struct hal_ev_hidhost_info),
	},
	{	/* HAL_EV_HIDHOST_PROTO_MODE */
		.handler = handle_proto_mode,
		.var_len = false,
		.data_len = sizeof(struct hal_ev_hidhost_proto_mode),
	},
	{	/* HAL_EV_HIDHOST_GET_REPORT */
		.handler = handle_get_report,
		.var_len = true,
		.data_len = sizeof(struct hal_ev_hidhost_get_report),
	},
	{	/* HAL_EV_HIDHOST_VIRTUAL_UNPLUG */
		.handler = handle_virtual_unplug,
		.var_len = false,
		.data_len = sizeof(struct hal_ev_hidhost_virtual_unplug),
	},
};

static bt_status_t hidhost_connect(bt_bdaddr_t *bd_addr)
{
	struct hal_cmd_hidhost_connect cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!bd_addr)
		return BT_STATUS_PARM_INVALID;

	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));

	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT,
					sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
{
	struct hal_cmd_hidhost_disconnect cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!bd_addr)
		return BT_STATUS_PARM_INVALID;

	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));

	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT,
					sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t virtual_unplug(bt_bdaddr_t *bd_addr)
{
	struct hal_cmd_hidhost_virtual_unplug cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!bd_addr)
		return BT_STATUS_PARM_INVALID;

	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));

	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST,
					HAL_OP_HIDHOST_VIRTUAL_UNPLUG,
					sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t set_info(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
{
	struct hal_cmd_hidhost_set_info cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!bd_addr)
		return BT_STATUS_PARM_INVALID;

	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
	cmd.attr = hid_info.attr_mask;
	cmd.subclass = hid_info.sub_class;
	cmd.app_id = hid_info.app_id;
	cmd.vendor = hid_info.vendor_id;
	cmd.product = hid_info.product_id;
	cmd.country = hid_info.ctry_code;
	cmd.descr_len = hid_info.dl_len;
	memcpy(cmd.descr, hid_info.dsc_list, cmd.descr_len);

	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO,
					sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t get_protocol(bt_bdaddr_t *bd_addr,
					bthh_protocol_mode_t protocol_mode)
{
	struct hal_cmd_hidhost_get_protocol cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!bd_addr)
		return BT_STATUS_PARM_INVALID;

	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));

	/* type match IPC type */
	cmd.mode = protocol_mode;

	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST,
				HAL_OP_HIDHOST_GET_PROTOCOL,
				sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t set_protocol(bt_bdaddr_t *bd_addr,
					bthh_protocol_mode_t protocol_mode)
{
	struct hal_cmd_hidhost_set_protocol cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!bd_addr)
		return BT_STATUS_PARM_INVALID;

	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));

	/* type match IPC type */
	cmd.mode = protocol_mode;

	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST,
				HAL_OP_HIDHOST_SET_PROTOCOL,
				sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t get_report(bt_bdaddr_t *bd_addr,
						bthh_report_type_t report_type,
						uint8_t report_id,
						int buffer_size)
{
	struct hal_cmd_hidhost_get_report cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!bd_addr)
		return BT_STATUS_PARM_INVALID;

	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
	cmd.id = report_id;
	cmd.buf_size = buffer_size;

	/* type match IPC type */
	cmd.type = report_type;

	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_REPORT,
			sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t set_report(bt_bdaddr_t *bd_addr,
						bthh_report_type_t report_type,
						char *report)
{
	uint8_t buf[BLUEZ_HAL_MTU];
	struct hal_cmd_hidhost_set_report *cmd = (void *) buf;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!bd_addr || !report)
		return BT_STATUS_PARM_INVALID;

	memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr));
	cmd->len = strlen(report);
	memcpy(cmd->data, report, cmd->len);

	/* type match IPC type */
	cmd->type = report_type;

	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_REPORT,
				sizeof(*cmd) + cmd->len, buf, 0, NULL, NULL);
}

static bt_status_t send_data(bt_bdaddr_t *bd_addr, char *data)
{
	uint8_t buf[BLUEZ_HAL_MTU];
	struct hal_cmd_hidhost_send_data *cmd = (void *) buf;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!bd_addr || !data)
		return BT_STATUS_PARM_INVALID;

	memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr));
	cmd->len = strlen(data);
	memcpy(cmd->data, data, cmd->len);

	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SEND_DATA,
				sizeof(*cmd) + cmd->len, buf, 0, NULL, NULL);
}

static bt_status_t init(bthh_callbacks_t *callbacks)
{
	struct hal_cmd_register_module cmd;
	int ret;

	DBG("");

	if (interface_ready())
		return BT_STATUS_DONE;

	/* store reference to user callbacks */
	cbacks = callbacks;

	hal_ipc_register(HAL_SERVICE_ID_HIDHOST, ev_handlers,
				sizeof(ev_handlers)/sizeof(ev_handlers[0]));

	cmd.service_id = HAL_SERVICE_ID_HIDHOST;

	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
					sizeof(cmd), &cmd, 0, NULL, NULL);

	if (ret != BT_STATUS_SUCCESS) {
		cbacks = NULL;
		hal_ipc_unregister(HAL_SERVICE_ID_HIDHOST);
	}

	return ret;
}

static void cleanup(void)
{
	struct hal_cmd_unregister_module cmd;

	DBG("");

	if (!interface_ready())
		return;

	cbacks = NULL;

	cmd.service_id = HAL_SERVICE_ID_HIDHOST;

	hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
					sizeof(cmd), &cmd, 0, NULL, NULL);

	hal_ipc_unregister(HAL_SERVICE_ID_HIDHOST);
}

static bthh_interface_t hidhost_if = {
	.size = sizeof(hidhost_if),
	.init = init,
	.connect = hidhost_connect,
	.disconnect = disconnect,
	.virtual_unplug = virtual_unplug,
	.set_info = set_info,
	.get_protocol = get_protocol,
	.set_protocol = set_protocol,
	.get_report = get_report,
	.set_report = set_report,
	.send_data = send_data,
	.cleanup = cleanup
};

bthh_interface_t *bt_get_hidhost_interface(void)
{
	return &hidhost_if;
}
