/*
 * 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 */

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

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

	memset(&hid_info, 0, sizeof(hid_info));

	/* This command is intentionally not supported. See comment from
	 * bt_hid_info() in android/hidhost.c */
	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_METHODCH(set_info, "<addr>"),
	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
};
