/*
 * 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 <stdio.h>
#include <ctype.h>

#include <hardware/bluetooth.h>
#include <hardware/bt_hh.h>

#include "if-main.h"
#include "pollhandler.h"
#include "../hal-utils.h"

const bthh_interface_t *if_hh = NULL;

SINTMAP(bthh_protocol_mode_t, -1, "(unknown)")
	DELEMENT(BTHH_REPORT_MODE),
	DELEMENT(BTHH_BOOT_MODE),
	DELEMENT(BTHH_UNSUPPORTED_MODE),
ENDMAP

SINTMAP(bthh_report_type_t, -1, "(unknown)")
	DELEMENT(BTHH_INPUT_REPORT),
	DELEMENT(BTHH_OUTPUT_REPORT),
	DELEMENT(BTHH_FEATURE_REPORT),
ENDMAP

SINTMAP(bthh_connection_state_t, -1, "(unknown)")
	DELEMENT(BTHH_CONN_STATE_CONNECTED),
	DELEMENT(BTHH_CONN_STATE_CONNECTING),
	DELEMENT(BTHH_CONN_STATE_DISCONNECTED),
	DELEMENT(BTHH_CONN_STATE_DISCONNECTING),
	DELEMENT(BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST),
	DELEMENT(BTHH_CONN_STATE_FAILED_KBD_FROM_HOST),
	DELEMENT(BTHH_CONN_STATE_FAILED_TOO_MANY_DEVICES),
	DELEMENT(BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER),
	DELEMENT(BTHH_CONN_STATE_FAILED_GENERIC),
	DELEMENT(BTHH_CONN_STATE_UNKNOWN),
ENDMAP

SINTMAP(bthh_status_t, -1, "(unknown)")
	DELEMENT(BTHH_OK),
	DELEMENT(BTHH_HS_HID_NOT_READY),
	DELEMENT(BTHH_HS_INVALID_RPT_ID),
	DELEMENT(BTHH_HS_TRANS_NOT_SPT),
	DELEMENT(BTHH_HS_INVALID_PARAM),
	DELEMENT(BTHH_HS_ERROR),
	DELEMENT(BTHH_ERR),
	DELEMENT(BTHH_ERR_SDP),
	DELEMENT(BTHH_ERR_PROTO),
	DELEMENT(BTHH_ERR_DB_FULL),
	DELEMENT(BTHH_ERR_TOD_UNSPT),
	DELEMENT(BTHH_ERR_NO_RES),
	DELEMENT(BTHH_ERR_AUTH_FAILED),
	DELEMENT(BTHH_ERR_HDL),
ENDMAP

static char connected_device_addr[MAX_ADDR_STR_LEN];
/*
 * Callback for connection state change.
 * state will have one of the values from bthh_connection_state_t
 */
static void connection_state_cb(bt_bdaddr_t *bd_addr,
						bthh_connection_state_t state)
{
	char addr[MAX_ADDR_STR_LEN];

	haltest_info("%s: bd_addr=%s connection_state=%s\n", __func__,
					bt_bdaddr_t2str(bd_addr, addr),
					bthh_connection_state_t2str(state));
	if (state == BTHH_CONN_STATE_CONNECTED)
		strcpy(connected_device_addr, addr);
}

/*
 * Callback for virtual unplug api.
 * the status of the virtual unplug
 */
static void virtual_unplug_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
{
	char addr[MAX_ADDR_STR_LEN];

	haltest_info("%s: bd_addr=%s hh_status=%s\n", __func__,
						bt_bdaddr_t2str(bd_addr, addr),
						bthh_status_t2str(hh_status));
}

/*
 * Callback for get hid info
 * hid_info will contain attr_mask, sub_class, app_id, vendor_id, product_id,
 * version, ctry_code, len
 */
static void hid_info_cb(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
{
	char addr[MAX_ADDR_STR_LEN];

	/* TODO: bluedroid does not seem to ever call this callback */
	haltest_info("%s: bd_addr=%s\n", __func__,
						bt_bdaddr_t2str(bd_addr, addr));
}

/*
 * Callback for get/set protocol api.
 * the protocol mode is one of the value from bthh_protocol_mode_t
 */
static void protocol_mode_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,
						bthh_protocol_mode_t mode)
{
	char addr[MAX_ADDR_STR_LEN];

	haltest_info("%s: bd_addr=%s hh_status=%s mode=%s\n", __func__,
					bt_bdaddr_t2str(bd_addr, addr),
					bthh_status_t2str(hh_status),
					bthh_protocol_mode_t2str(mode));
}

/*
 * Callback for get/set_idle_time api.
 */
static void idle_time_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,
								int idle_rate)
{
	char addr[MAX_ADDR_STR_LEN];

	haltest_info("%s: bd_addr=%s hh_status=%s idle_rate=%d\n", __func__,
				bt_bdaddr_t2str(bd_addr, addr),
				bthh_status_t2str(hh_status), idle_rate);
}


/*
 * Callback for get report api.
 * if status is ok rpt_data contains the report data
 */
static void get_report_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,
						uint8_t *rpt_data, int rpt_size)
{
	char addr[MAX_ADDR_STR_LEN];

	/* TODO: print actual report */
	haltest_info("%s: bd_addr=%s hh_status=%s rpt_size=%d\n", __func__,
					bt_bdaddr_t2str(bd_addr, addr),
					bthh_status_t2str(hh_status), rpt_size);
}

static bthh_callbacks_t bthh_callbacks = {
	.size = sizeof(bthh_callbacks),
	.connection_state_cb = connection_state_cb,
	.hid_info_cb = hid_info_cb,
	.protocol_mode_cb = protocol_mode_cb,
	.idle_time_cb = idle_time_cb,
	.get_report_cb = get_report_cb,
	.virtual_unplug_cb = virtual_unplug_cb
};

/* init */

static void init_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_hh);

	EXEC(if_hh->init, &bthh_callbacks);
}

/* connect */

static void connect_c(int argc, const char **argv, enum_func *enum_func,
								void **user)
{
	if (argc == 3) {
		*user = (void *) connected_device_addr;
		*enum_func = enum_one_string;
	}
}

static void connect_p(int argc, const char **argv)
{
	bt_bdaddr_t addr;

	RETURN_IF_NULL(if_hh);
	VERIFY_ADDR_ARG(2, &addr);

	EXEC(if_hh->connect, &addr);
}

/* disconnect */

/* Same completion as connect_c */
#define disconnect_c connect_c

static void disconnect_p(int argc, const char **argv)
{
	bt_bdaddr_t addr;

	RETURN_IF_NULL(if_hh);
	VERIFY_ADDR_ARG(2, &addr);

	EXEC(if_hh->disconnect, &addr);
}

/* virtual_unplug */

/* Same completion as connect_c */
#define virtual_unplug_c connect_c

static void virtual_unplug_p(int argc, const char **argv)
{
	bt_bdaddr_t addr;

	RETURN_IF_NULL(if_hh);
	VERIFY_ADDR_ARG(2, &addr);

	EXEC(if_hh->virtual_unplug, &addr);
}

/* set_info */

static void set_info_p(int argc, const char **argv)
{
	bt_bdaddr_t addr;
	bthh_hid_info_t hid_info;

	RETURN_IF_NULL(if_hh);
	VERIFY_ADDR_ARG(2, &addr);
	/* TODO: set_info does not seem to be called anywhere */

	EXEC(if_hh->set_info, &addr, hid_info);
}

/* get_protocol */

static void get_protocol_c(int argc, const char **argv, enum_func *enum_func,
								void **user)
{
	if (argc == 3) {
		*user = connected_device_addr;
		*enum_func = enum_one_string;
	} else if (argc == 4) {
		*user = TYPE_ENUM(bthh_protocol_mode_t);
		*enum_func = enum_defines;
	}
}

static void get_protocol_p(int argc, const char **argv)
{
	bt_bdaddr_t addr;
	bthh_protocol_mode_t protocolMode;

	RETURN_IF_NULL(if_hh);
	VERIFY_ADDR_ARG(2, &addr);

	if (argc < 4) {
		haltest_error("No protocol mode specified\n");
		return;
	}
	protocolMode = str2bthh_protocol_mode_t(argv[3]);

	EXEC(if_hh->get_protocol, &addr, protocolMode);
}

/* set_protocol */

/* Same completion as get_protocol_c */
#define set_protocol_c get_protocol_c

static void set_protocol_p(int argc, const char **argv)
{
	bt_bdaddr_t addr;
	bthh_protocol_mode_t protocolMode;

	RETURN_IF_NULL(if_hh);
	VERIFY_ADDR_ARG(2, &addr);

	if (argc < 4) {
		haltest_error("No protocol mode specified\n");
		return;
	}
	protocolMode = str2bthh_protocol_mode_t(argv[3]);

	EXEC(if_hh->set_protocol, &addr, protocolMode);
}

/* get_report */

static void get_report_c(int argc, const char **argv, enum_func *enum_func,
								void **user)
{
	if (argc == 3) {
		*user = connected_device_addr;
		*enum_func = enum_one_string;
	} else if (argc == 4) {
		*user = TYPE_ENUM(bthh_report_type_t);
		*enum_func = enum_defines;
	}
}

static void get_report_p(int argc, const char **argv)
{
	bt_bdaddr_t addr;
	bthh_report_type_t reportType;
	uint8_t reportId;
	int bufferSize;

	RETURN_IF_NULL(if_hh);
	VERIFY_ADDR_ARG(2, &addr);

	if (argc < 4) {
		haltest_error("No report type specified\n");
		return;
	}
	reportType = str2bthh_report_type_t(argv[3]);

	if (argc < 5) {
		haltest_error("No reportId specified\n");
		return;
	}
	reportId = (uint8_t) atoi(argv[4]);

	if (argc < 6) {
		haltest_error("No bufferSize specified\n");
		return;
	}
	bufferSize = atoi(argv[5]);

	EXEC(if_hh->get_report, &addr, reportType, reportId, bufferSize);
}

/* set_report */

static void set_report_c(int argc, const char **argv, enum_func *enum_func,
								void **user)
{
	if (argc == 3) {
		*user = connected_device_addr;
		*enum_func = enum_one_string;
	} else if (argc == 4) {
		*user = TYPE_ENUM(bthh_report_type_t);
		*enum_func = enum_defines;
	}
}

static void set_report_p(int argc, const char **argv)
{
	bt_bdaddr_t addr;
	bthh_report_type_t reportType;

	RETURN_IF_NULL(if_hh);
	VERIFY_ADDR_ARG(2, &addr);

	if (argc <= 3) {
		haltest_error("No report type specified\n");
		return;
	}
	reportType = str2bthh_report_type_t(argv[3]);

	if (argc <= 4) {
		haltest_error("No report specified\n");
		return;
	}

	EXEC(if_hh->set_report, &addr, reportType, (char *) argv[4]);
}

/* send_data */

static void send_data_c(int argc, const char **argv, enum_func *enum_func,
								void **user)
{
	if (argc == 3) {
		*user = connected_device_addr;
		*enum_func = enum_one_string;
	}
}

static void send_data_p(int argc, const char **argv)
{
	bt_bdaddr_t addr;

	RETURN_IF_NULL(if_hh);
	VERIFY_ADDR_ARG(2, &addr);

	if (argc <= 3) {
		haltest_error("No data to send specified\n");
		return;
	}

	EXEC(if_hh->send_data, &addr, (char *) argv[3]);
}

/* cleanup */

static void cleanup_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_hh);

	EXECV(if_hh->cleanup);
}

/* Methods available in bthh_interface_t */
static struct method methods[] = {
	STD_METHOD(init),
	STD_METHODCH(connect, "<addr>"),
	STD_METHODCH(disconnect, "<addr>"),
	STD_METHODCH(virtual_unplug, "<addr>"),
	STD_METHOD(set_info),
	STD_METHODCH(get_protocol, "<addr> <mode>"),
	STD_METHODCH(set_protocol, "<addr> <mode>"),
	STD_METHODCH(get_report, "<addr> <type> <report_id> <size>"),
	STD_METHODCH(set_report, "<addr> <type> <hex_encoded_report>"),
	STD_METHODCH(send_data, "<addr> <hex_encoded_data>"),
	STD_METHOD(cleanup),
	END_METHOD
};

const struct interface hh_if = {
	.name = "hidhost",
	.methods = methods
};
