/*
 * 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 <string.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
};
