/*
 * 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 <string.h>
#include <stdint.h>

#include "hal-utils.h"

/*
 * converts uuid to string
 * buf should be at least 39 bytes
 *
 * returns string representation of uuid
 */
const char *bt_uuid_t2str(const uint8_t *uuid, char *buf)
{
	int shift = 0;
	unsigned int i;
	int is_bt;

	if (!uuid)
		return strcpy(buf, "NULL");

	is_bt = !memcmp(&uuid[4], &BT_BASE_UUID[4], HAL_UUID_LEN - 4);

	for (i = 0; i < HAL_UUID_LEN; i++) {
		if (i == 4 && is_bt)
			break;

		if (i == 4 || i == 6 || i == 8 || i == 10) {
			buf[i * 2 + shift] = '-';
			shift++;
		}
		sprintf(buf + i * 2 + shift, "%02x", uuid[i]);
	}

	return buf;
}

const char *btuuid2str(const uint8_t *uuid)
{
	static char buf[MAX_UUID_STR_LEN];

	return bt_uuid_t2str(uuid, buf);
}

INTMAP(bt_status_t, -1, "(unknown)")
	DELEMENT(BT_STATUS_SUCCESS),
	DELEMENT(BT_STATUS_FAIL),
	DELEMENT(BT_STATUS_NOT_READY),
	DELEMENT(BT_STATUS_NOMEM),
	DELEMENT(BT_STATUS_BUSY),
	DELEMENT(BT_STATUS_DONE),
	DELEMENT(BT_STATUS_UNSUPPORTED),
	DELEMENT(BT_STATUS_PARM_INVALID),
	DELEMENT(BT_STATUS_UNHANDLED),
	DELEMENT(BT_STATUS_AUTH_FAILURE),
	DELEMENT(BT_STATUS_RMT_DEV_DOWN),
ENDMAP

INTMAP(bt_state_t, -1, "(unknown)")
	DELEMENT(BT_STATE_OFF),
	DELEMENT(BT_STATE_ON),
ENDMAP

INTMAP(bt_device_type_t, -1, "(unknown)")
	DELEMENT(BT_DEVICE_DEVTYPE_BREDR),
	DELEMENT(BT_DEVICE_DEVTYPE_BLE),
	DELEMENT(BT_DEVICE_DEVTYPE_DUAL),
ENDMAP

INTMAP(bt_scan_mode_t, -1, "(unknown)")
	DELEMENT(BT_SCAN_MODE_NONE),
	DELEMENT(BT_SCAN_MODE_CONNECTABLE),
	DELEMENT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE),
ENDMAP

INTMAP(bt_discovery_state_t, -1, "(unknown)")
	DELEMENT(BT_DISCOVERY_STOPPED),
	DELEMENT(BT_DISCOVERY_STARTED),
ENDMAP

INTMAP(bt_acl_state_t, -1, "(unknown)")
	DELEMENT(BT_ACL_STATE_CONNECTED),
	DELEMENT(BT_ACL_STATE_DISCONNECTED),
ENDMAP

INTMAP(bt_bond_state_t, -1, "(unknown)")
	DELEMENT(BT_BOND_STATE_NONE),
	DELEMENT(BT_BOND_STATE_BONDING),
	DELEMENT(BT_BOND_STATE_BONDED),
ENDMAP

INTMAP(bt_ssp_variant_t, -1, "(unknown)")
	DELEMENT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION),
	DELEMENT(BT_SSP_VARIANT_PASSKEY_ENTRY),
	DELEMENT(BT_SSP_VARIANT_CONSENT),
	DELEMENT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION),
ENDMAP

INTMAP(bt_property_type_t, -1, "(unknown)")
	DELEMENT(BT_PROPERTY_BDNAME),
	DELEMENT(BT_PROPERTY_BDADDR),
	DELEMENT(BT_PROPERTY_UUIDS),
	DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE),
	DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE),
	DELEMENT(BT_PROPERTY_SERVICE_RECORD),
	DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE),
	DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES),
	DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
	DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
	DELEMENT(BT_PROPERTY_REMOTE_RSSI),
	DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
	DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
ENDMAP

INTMAP(bt_cb_thread_evt, -1, "(unknown)")
	DELEMENT(ASSOCIATE_JVM),
	DELEMENT(DISASSOCIATE_JVM),
ENDMAP

/* Find first index of given value in table m */
int int2str_findint(int v, const struct int2str m[])
{
	int i;

	for (i = 0; m[i].str; ++i) {
		if (m[i].val == v)
			return i;
	}
	return -1;
}

/* Find first index of given string in table m */
int int2str_findstr(const char *str, const struct int2str m[])
{
	int i;

	for (i = 0; m[i].str; ++i) {
		if (strcmp(m[i].str, str) == 0)
			return i;
	}
	return -1;
}

/*
 * convert bd_addr to string
 * buf must be at least 18 char long
 *
 * returns buf
 */
const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
{
	const uint8_t *p = bd_addr->address;

	if (!bd_addr)
		return strcpy(buf, "NULL");

	snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
					p[0], p[1], p[2], p[3], p[4], p[5]);

	return buf;
}

/* converts string to bt_bdaddr_t */
void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr)
{
	uint8_t *p = bd_addr->address;

	sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
				&p[0], &p[1], &p[2], &p[3], &p[4], &p[5]);
}

/* converts string to uuid */
void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
{
	int i = 0;

	memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t));

	while (*str && i < (int) sizeof(bt_uuid_t)) {
		while (*str == '-')
			str++;

		if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1)
			break;

		i++;
		str += 2;
	}
}

const char *enum_defines(void *v, int i)
{
	const struct int2str *m = v;

	return m[i].str != NULL ? m[i].str : NULL;
}

const char *enum_strings(void *v, int i)
{
	const char **m = v;

	return m[i] != NULL ? m[i] : NULL;
}

const char *enum_one_string(void *v, int i)
{
	const char *m = v;

	return (i == 0) && (m[0] != 0) ? m : NULL;
}

const char *bdaddr2str(const bt_bdaddr_t *bd_addr)
{
	static char buf[MAX_ADDR_STR_LEN];

	return bt_bdaddr_t2str(bd_addr, buf);
}

const char *btproperty2str(const bt_property_t *property)
{
	static char buf[4096];
	char *p;

	p = buf + sprintf(buf, "type=%s len=%d val=",
					bt_property_type_t2str(property->type),
					property->len);

	switch (property->type) {
	case BT_PROPERTY_BDNAME:
	case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
		snprintf(p, property->len + 1, "%s",
					((bt_bdname_t *) property->val)->name);
		break;

	case BT_PROPERTY_BDADDR:
		sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val));
		break;

	case BT_PROPERTY_CLASS_OF_DEVICE:
		sprintf(p, "%06x", *((int *) property->val));
		break;

	case BT_PROPERTY_TYPE_OF_DEVICE:
		sprintf(p, "%s", bt_device_type_t2str(
				*((bt_device_type_t *) property->val)));
		break;

	case BT_PROPERTY_REMOTE_RSSI:
		sprintf(p, "%d", *((char *) property->val));
		break;

	case BT_PROPERTY_ADAPTER_SCAN_MODE:
		sprintf(p, "%s",
			bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val)));
		break;

	case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
		sprintf(p, "%d", *((int *) property->val));
		break;

	case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
		{
			int count = property->len / sizeof(bt_bdaddr_t);
			char *ptr = property->val;

			strcat(p, "{");

			while (count--) {
				strcat(p, bdaddr2str((bt_bdaddr_t *) ptr));
				if (count)
					strcat(p, ", ");
				ptr += sizeof(bt_bdaddr_t);
			}

			strcat(p, "}");

		}
		break;

	case BT_PROPERTY_UUIDS:
		{
			int count = property->len / sizeof(bt_uuid_t);
			uint8_t *ptr = property->val;

			strcat(p, "{");

			while (count--) {
				strcat(p, btuuid2str(ptr));
				if (count)
					strcat(p, ", ");
				ptr += sizeof(bt_uuid_t);
			}

			strcat(p, "}");

		}
		break;

	case BT_PROPERTY_SERVICE_RECORD:
		{
			bt_service_record_t *rec = property->val;

			sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu),
						rec->channel, rec->name);
		}
		break;

	default:
		sprintf(p, "%p", property->val);
	}

	return buf;
}
