/*
 * Copyright (C) 2014 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 <cutils/properties.h>

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

#define MODE_PROPERTY_NAME "persist.sys.bluetooth.handsfree"

static const bthf_callbacks_t *cbs = NULL;

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

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

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

static void handle_audio_state(void *buf, uint16_t len)
{
	struct hal_ev_handsfree_audio_state *ev = buf;

	if (cbs->audio_state_cb)
		cbs->audio_state_cb(ev->state, (bt_bdaddr_t *) (ev->bdaddr));
}

static void handle_vr_state(void *buf, uint16_t len)
{
	struct hal_ev_handsfree_vr_state *ev = buf;

	if (cbs->vr_cmd_cb)
		cbs->vr_cmd_cb(ev->state);
}

static void handle_answer(void *buf, uint16_t len)
{
	if (cbs->answer_call_cmd_cb)
		cbs->answer_call_cmd_cb();
}

static void handle_hangup(void *buf, uint16_t len)
{
	if (cbs->hangup_call_cmd_cb)
		cbs->hangup_call_cmd_cb();
}

static void handle_volume(void *buf, uint16_t len)
{
	struct hal_ev_handsfree_volume *ev = buf;

	if (cbs->volume_cmd_cb)
		cbs->volume_cmd_cb(ev->type, ev->volume);
}

static void handle_dial(void *buf, uint16_t len)
{
	struct hal_ev_handsfree_dial *ev = buf;
	uint16_t num_len = ev->number_len;

	if (len != sizeof(*ev) + num_len ||
			(num_len != 0 && ev->number[num_len - 1] != '\0')) {
		error("invalid dial event, aborting");
		exit(EXIT_FAILURE);
	}

	if (!cbs->dial_call_cmd_cb)
		return;

	if (ev->number_len)
		cbs->dial_call_cmd_cb((char *) ev->number);
	else
		cbs->dial_call_cmd_cb(NULL);
}

static void handle_dtmf(void *buf, uint16_t len)
{
	struct hal_ev_handsfree_dtmf *ev = buf;

	if (cbs->dtmf_cmd_cb)
		cbs->dtmf_cmd_cb(ev->tone);
}

static void handle_nrec(void *buf, uint16_t len)
{
	struct hal_ev_handsfree_nrec *ev = buf;

	if (cbs->nrec_cmd_cb)
		cbs->nrec_cmd_cb(ev->nrec);
}

static void handle_chld(void *buf, uint16_t len)
{
	struct hal_ev_handsfree_chld *ev = buf;

	if (cbs->chld_cmd_cb)
		cbs->chld_cmd_cb(ev->chld);
}

static void handle_cnum(void *buf, uint16_t len)
{
	if (cbs->cnum_cmd_cb)
		cbs->cnum_cmd_cb();
}

static void handle_cind(void *buf, uint16_t len)
{
	if (cbs->cind_cmd_cb)
		cbs->cind_cmd_cb();
}

static void handle_cops(void *buf, uint16_t len)
{
	if (cbs->cops_cmd_cb)
		cbs->cops_cmd_cb();
}

static void handle_clcc(void *buf, uint16_t len)
{
	if (cbs->clcc_cmd_cb)
		cbs->clcc_cmd_cb();
}

static void handle_unknown_at(void *buf, uint16_t len)
{
	struct hal_ev_handsfree_unknown_at *ev = buf;

	if (len != sizeof(*ev) + ev->len ||
			(ev->len != 0 && ev->buf[ev->len - 1] != '\0')) {
		error("invalid unknown command event, aborting");
		exit(EXIT_FAILURE);
	}

	if (cbs->unknown_at_cmd_cb)
		cbs->unknown_at_cmd_cb((char *) ev->buf);
}

static void handle_hsp_key_press(void *buf, uint16_t len)
{
	if (cbs->key_pressed_cmd_cb)
		cbs->key_pressed_cmd_cb();
}

/* 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_HANDSFREE_CONN_STATE */
	{handle_conn_state, false, sizeof(struct hal_ev_handsfree_conn_state)},
	/* HAL_EV_HANDSFREE_AUDIO_STATE */
	{handle_audio_state, false,
				sizeof(struct hal_ev_handsfree_audio_state)},
	/* HAL_EV_HANDSFREE_VR */
	{handle_vr_state, false, sizeof(struct hal_ev_handsfree_vr_state)},
	/*HAL_EV_HANDSFREE_ANSWER */
	{handle_answer, false, 0},
	/*HAL_EV_HANDSFREE_HANGUP */
	{handle_hangup, false, 0},
	/* HAL_EV_HANDSFREE_VOLUME */
	{handle_volume, false, sizeof(struct hal_ev_handsfree_volume)},
	/* HAL_EV_HANDSFREE_DIAL */
	{handle_dial, true, sizeof(struct hal_ev_handsfree_dial)},
	/* HAL_EV_HANDSFREE_DTMF */
	{handle_dtmf, false, sizeof(struct hal_ev_handsfree_dtmf)},
	/* HAL_EV_HANDSFREE_NREC */
	{handle_nrec, false, sizeof(struct hal_ev_handsfree_nrec)},
	/* HAL_EV_HANDSFREE_CHLD */
	{handle_chld, false, sizeof(struct hal_ev_handsfree_chld)},
	/* HAL_EV_HANDSFREE_CNUM */
	{handle_cnum, false, 0},
	/* HAL_EV_HANDSFREE_CIND */
	{handle_cind, false, 0},
	/* HAL_EV_HANDSFREE_COPS */
	{handle_cops, false, 0},
	/* HAL_EV_HANDSFREE_CLCC */
	{handle_clcc, false, 0},
	/* HAL_EV_HANDSFREE_UNKNOWN_AT */
	{handle_unknown_at, true, sizeof(struct hal_ev_handsfree_unknown_at)},
	/* HAL_EV_HANDSFREE_HSP_KEY_PRESS */
	{handle_hsp_key_press, false, 0},
};

static uint8_t get_mode(void)
{
	char value[PROPERTY_VALUE_MAX];

	if (property_get(MODE_PROPERTY_NAME, value, "") > 0 &&
					(!strcasecmp(value, "hfp")))
		return HAL_MODE_HANDSFREE_HFP;

	if (property_get(MODE_PROPERTY_NAME, value, "") > 0 &&
					(!strcasecmp(value, "hfp_wbs")))
		return HAL_MODE_HANDSFREE_HFP_WBS;

	return HAL_MODE_HANDSFREE_HSP_ONLY;
}

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

	DBG("");

	if (interface_ready())
		return BT_STATUS_DONE;

	cbs = callbacks;

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

	cmd.service_id = HAL_SERVICE_ID_HANDSFREE;
	cmd.mode = get_mode();

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

	if (ret != BT_STATUS_SUCCESS) {
		cbs = NULL;
		hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE);
	}

	return ret;
}

static bt_status_t handsfree_connect(bt_bdaddr_t *bd_addr)
{
	struct hal_cmd_handsfree_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_HANDSFREE, HAL_OP_HANDSFREE_CONNECT,
					sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
{
	struct hal_cmd_handsfree_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_HANDSFREE,
				HAL_OP_HANDSFREE_DISCONNECT, sizeof(cmd), &cmd,
				0, NULL, NULL);
}

static bt_status_t connect_audio(bt_bdaddr_t *bd_addr)
{
	struct hal_cmd_handsfree_connect_audio 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_HANDSFREE,
				HAL_OP_HANDSFREE_CONNECT_AUDIO, sizeof(cmd),
				&cmd, 0, NULL, NULL);
}

static bt_status_t disconnect_audio(bt_bdaddr_t *bd_addr)
{
	struct hal_cmd_handsfree_disconnect_audio 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_HANDSFREE,
				HAL_OP_HANDSFREE_DISCONNECT_AUDIO, sizeof(cmd),
				&cmd, 0, NULL, NULL);
}

static bt_status_t start_voice_recognition(void)
{
	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_START_VR,
							0, NULL, 0, NULL, NULL);
}

static bt_status_t stop_voice_recognition(void)
{
	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_STOP_VR,
							0, NULL, 0, NULL, NULL);
}

static bt_status_t volume_control(bthf_volume_type_t type, int volume)
{
	struct hal_cmd_handsfree_volume_control cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	cmd.type = type;
	cmd.volume = volume;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
				HAL_OP_HANDSFREE_VOLUME_CONTROL, sizeof(cmd),
				&cmd, 0, NULL, NULL);
}

static bt_status_t device_status_notification(bthf_network_state_t state,
						bthf_service_type_t type,
						int signal, int battery)
{
	struct hal_cmd_handsfree_device_status_notif cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	cmd.state = state;
	cmd.type = type;
	cmd.signal = signal;
	cmd.battery = battery;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF,
					sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t cops_response(const char *cops)
{
	char buf[IPC_MTU];
	struct hal_cmd_handsfree_cops_response *cmd = (void *) buf;
	size_t len;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!cops)
		return BT_STATUS_PARM_INVALID;

	cmd->len = strlen(cops) + 1;
	memcpy(cmd->buf, cops, cmd->len);

	len = sizeof(*cmd) + cmd->len;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
						HAL_OP_HANDSFREE_COPS_RESPONSE,
						len, cmd, 0, NULL, NULL);
}

static bt_status_t cind_response(int svc, int num_active, int num_held,
					bthf_call_state_t state, int signal,
					int roam, int batt_chg)
{
	struct hal_cmd_handsfree_cind_response cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	cmd.svc = svc;
	cmd.num_active = num_active;
	cmd.num_held = num_held;
	cmd.state = state;
	cmd.signal = signal;
	cmd.roam = roam;
	cmd.batt_chg = batt_chg;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_CIND_RESPONSE,
					sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t formatted_at_response(const char *rsp)
{
	char buf[IPC_MTU];
	struct hal_cmd_handsfree_formatted_at_response *cmd = (void *) buf;
	size_t len;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	if (!rsp)
		return BT_STATUS_PARM_INVALID;

	cmd->len = strlen(rsp) + 1;
	memcpy(cmd->buf, rsp, cmd->len);

	len = sizeof(*cmd) + cmd->len;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE,
					len, cmd, 0, NULL, NULL);
}

static bt_status_t at_response(bthf_at_response_t response, int error)
{
	struct hal_cmd_handsfree_at_response cmd;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	cmd.response = response;
	cmd.error = error;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_AT_RESPONSE,
					sizeof(cmd), &cmd, 0, NULL, NULL);
}

static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
					bthf_call_state_t state,
					bthf_call_mode_t mode,
					bthf_call_mpty_type_t mpty,
					const char *number,
					bthf_call_addrtype_t type)
{
	char buf[IPC_MTU];
	struct hal_cmd_handsfree_clcc_response *cmd = (void *) buf;
	size_t len;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	cmd->index = index;
	cmd->dir = dir;
	cmd->state = state;
	cmd->mode = mode;
	cmd->mpty = mpty;
	cmd->type = type;

	if (number) {
		cmd->number_len = strlen(number) + 1;
		memcpy(cmd->number, number, cmd->number_len);
	} else {
		cmd->number_len = 0;
	}

	len = sizeof(*cmd) + cmd->number_len;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
						HAL_OP_HANDSFREE_CLCC_RESPONSE,
						len, cmd, 0, NULL, NULL);
}

static bt_status_t phone_state_change(int num_active, int num_held,
					bthf_call_state_t state,
					const char *number,
					bthf_call_addrtype_t type)
{
	char buf[IPC_MTU];
	struct hal_cmd_handsfree_phone_state_change *cmd = (void *) buf;
	size_t len;

	DBG("");

	if (!interface_ready())
		return BT_STATUS_NOT_READY;

	cmd->num_active = num_active;
	cmd->num_held = num_held;
	cmd->state = state;
	cmd->type = type;

	if (number) {
		cmd->number_len = strlen(number) + 1;
		memcpy(cmd->number, number, cmd->number_len);
	} else {
		cmd->number_len = 0;
	}

	len = sizeof(*cmd) + cmd->number_len;

	return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
					HAL_OP_HANDSFREE_PHONE_STATE_CHANGE,
					len, cmd, 0, NULL, NULL);
}

static void cleanup(void)
{
	struct hal_cmd_unregister_module cmd;

	DBG("");

	if (!interface_ready())
		return;

	cbs = NULL;

	cmd.service_id = HAL_SERVICE_ID_HANDSFREE;

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

	hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE);
}

static bthf_interface_t iface = {
	.size = sizeof(iface),
	.init = init,
	.connect = handsfree_connect,
	.disconnect = disconnect,
	.connect_audio = connect_audio,
	.disconnect_audio = disconnect_audio,
	.start_voice_recognition = start_voice_recognition,
	.stop_voice_recognition = stop_voice_recognition,
	.volume_control = volume_control,
	.device_status_notification = device_status_notification,
	.cops_response = cops_response,
	.cind_response = cind_response,
	.formatted_at_response = formatted_at_response,
	.at_response = at_response,
	.clcc_response = clcc_response,
	.phone_state_change = phone_state_change,
	.cleanup = cleanup
};

bthf_interface_t *bt_get_handsfree_interface(void)
{
	return &iface;
}
