/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <misc/printk.h>
#include <gpio.h>
#include <device.h>
#include <string.h>

#include <display/mb_display.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/uuid.h>
#include <bluetooth/conn.h>
#include <bluetooth/gatt.h>


#include "pong.h"

#define SCAN_TIMEOUT     K_SECONDS(2)

#define APPEARANCE       0

#define PONG_SVC_UUID	0x90, 0x6c, 0x55, 0x0f, 0xee, 0x6f, 0x4d, 0x0d, \
			0xa1, 0x7e, 0x24, 0x4e, 0x38, 0xea, 0x4f, 0xf9
#define PONG_CHR_UUID	0xdd, 0x94, 0xaf, 0xd7, 0xcd, 0x2c, 0x40, 0xc6, \
			0xb5, 0x82, 0x6a, 0xc5, 0x1c, 0x8f, 0xbf, 0xab

static struct bt_uuid_128 pong_svc_uuid = BT_UUID_INIT_128(PONG_SVC_UUID);
static struct bt_uuid_128 pong_chr_uuid = BT_UUID_INIT_128(PONG_CHR_UUID);
static struct bt_uuid *gatt_ccc_uuid = BT_UUID_GATT_CCC;

static struct bt_gatt_discover_params discov_param;
static struct bt_gatt_subscribe_params subscribe_param;

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA_BYTES(BT_DATA_UUID128_ALL, PONG_SVC_UUID),
};

static struct bt_conn *default_conn;

static const struct bt_gatt_attr *local_attr;
static u16_t remote_handle;
static bool remote_ready;
static bool initiator;

static struct k_delayed_work ble_work;

static bool connect_canceled;

static enum {
	BLE_DISCONNECTED,
	BLE_SCAN_START,
	BLE_SCAN,
	BLE_CONNECT_CREATE,
	BLE_CONNECT_CANCEL,
	BLE_ADV_START,
	BLE_ADVERTISING,
	BLE_CONNECTED,
} ble_state;

enum {
	BLE_BALL_INFO = 0x00,
	BLE_LOST = 0x01,
};

struct ble_ball_info {
	s8_t x_pos;
	s8_t y_pos;
	s8_t x_vel;
	s8_t y_vel;
} __packed;

struct ble_data {
	u8_t op;
	union {
		struct ble_ball_info ball;
	};
} __packed;

#define BALL_INFO_LEN (1 + sizeof(struct ble_ball_info))

void ble_send_ball(s8_t x_pos, s8_t y_pos, s8_t x_vel, s8_t y_vel)
{
	struct ble_data data = {
		.op           = BLE_BALL_INFO,
		.ball.x_pos   = x_pos,
		.ball.y_pos   = y_pos,
		.ball.x_vel   = x_vel,
		.ball.y_vel   = y_vel,
	};
	int err;

	if (!default_conn || !remote_ready) {
		printk("ble_send_ball(): not ready\n");
		return;
	}

	printk("ble_send_ball(%d, %d, %d, %d)\n", x_pos, y_pos, x_vel, y_vel);

	err = bt_gatt_notify(default_conn, local_attr, &data, BALL_INFO_LEN);
	if (err) {
		printk("GATT notify failed (err %d)\n", err);
	}
}

void ble_send_lost(void)
{
	u8_t lost = BLE_LOST;
	int err;

	if (!default_conn || !remote_ready) {
		printk("ble_send_lost(): not ready\n");
		return;
	}

	err = bt_gatt_notify(default_conn, local_attr, &lost, sizeof(lost));
	if (err) {
		printk("GATT notify failed (err %d)\n", err);
	}
}

static u8_t notify_func(struct bt_conn *conn,
			struct bt_gatt_subscribe_params *param,
			const void *buf, u16_t len)
{
	const struct ble_data *data = buf;

	printk("notify_func() data %p len %u\n", data, len);

	if (!data || !len) {
		printk("Unsubscribed, disconnecting...\n");
		remote_handle = 0U;
		if (default_conn) {
			bt_conn_disconnect(default_conn,
					   BT_HCI_ERR_REMOTE_USER_TERM_CONN);
		}
		return BT_GATT_ITER_STOP;
	}

	switch (data->op) {
	case BLE_BALL_INFO:
		if (len < BALL_INFO_LEN) {
			printk("Too small ball info\n");
			break;
		}

		pong_ball_received(data->ball.x_pos, data->ball.y_pos,
				   data->ball.x_vel, data->ball.y_vel);
		break;
	case BLE_LOST:
		pong_remote_lost();
		break;
	default:
		printk("Unknown op 0x%02x\n", data->op);
	}

	return BT_GATT_ITER_CONTINUE;
}

static u8_t discover_func(struct bt_conn *conn,
			  const struct bt_gatt_attr *attr,
			  struct bt_gatt_discover_params *param)
{
	int err;

	if (!attr) {
		printk("Discover complete\n");
		(void)memset(&discov_param, 0, sizeof(discov_param));
		return BT_GATT_ITER_STOP;
	}

	printk("Attribute handle %u\n", attr->handle);

	if (param->uuid == &pong_svc_uuid.uuid) {
		printk("Pong service discovered\n");
		discov_param.uuid = &pong_chr_uuid.uuid;
		discov_param.start_handle = attr->handle + 1;
		discov_param.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &discov_param);
		if (err) {
			printk("Char Discovery failed (err %d)\n", err);
		}
	} else if (param->uuid == &pong_chr_uuid.uuid) {
		printk("Pong characteristic discovered\n");
		discov_param.uuid = gatt_ccc_uuid;
		discov_param.start_handle = attr->handle + 2;
		discov_param.type = BT_GATT_DISCOVER_DESCRIPTOR;
		subscribe_param.value_handle = attr->handle + 1;

		err = bt_gatt_discover(conn, &discov_param);
		if (err) {
			printk("CCC Discovery failed (err %d)\n", err);
		}
	} else {
		printk("Pong CCC discovered\n");

		subscribe_param.notify = notify_func;
		subscribe_param.value = BT_GATT_CCC_NOTIFY;
		subscribe_param.ccc_handle = attr->handle;

		printk("CCC handle 0x%04x Value handle 0x%04x\n",
		       subscribe_param.ccc_handle,
		       subscribe_param.value_handle);

		err = bt_gatt_subscribe(conn, &subscribe_param);
		if (err && err != -EALREADY) {
			printk("Subscribe failed (err %d)\n", err);
		} else {
			printk("Subscribed\n");
		}

		remote_handle = attr->handle;
	}

	if (remote_handle && remote_ready) {
		pong_conn_ready(initiator);
	}

	return BT_GATT_ITER_STOP;
}

static void connected(struct bt_conn *conn, u8_t err)
{
	struct bt_conn_info info;

	if (err) {
		printk("Connection failed (err %u)\n", err);
		return;
	}

	if (ble_state == BLE_ADVERTISING) {
		bt_le_adv_stop();
	}

	if (!default_conn) {
		default_conn = bt_conn_ref(conn);
	}

	bt_conn_get_info(conn, &info);
	initiator = (info.role == BT_CONN_ROLE_MASTER);
	remote_ready = false;
	remote_handle = 0U;

	printk("Connected\n");
	ble_state = BLE_CONNECTED;

	k_delayed_work_submit(&ble_work, K_NO_WAIT);
}

static void disconnected(struct bt_conn *conn, u8_t reason)
{
	printk("Disconnected (reason %u)\n", reason);

	if (default_conn) {
		bt_conn_unref(default_conn);
		default_conn = NULL;
	}

	remote_handle = 0U;

	if (ble_state == BLE_CONNECTED) {
		ble_state = BLE_DISCONNECTED;
		pong_remote_disconnected();
	}
}

static struct bt_conn_cb conn_callbacks = {
	.connected = connected,
	.disconnected = disconnected,
};

void ble_connect(void)
{
	if (ble_state != BLE_DISCONNECTED) {
		printk("Not ready to connect\n");
		return;
	}

	ble_state = BLE_SCAN_START;
	k_delayed_work_submit(&ble_work, K_NO_WAIT);
}

void ble_cancel_connect(void)
{
	printk("ble_cancel_connect()\n");

	k_delayed_work_cancel(&ble_work);

	switch (ble_state) {
	case BLE_DISCONNECTED:
		break;
	case BLE_SCAN_START:
		ble_state = BLE_DISCONNECTED;
		break;
	case BLE_SCAN:
		connect_canceled = true;
		k_delayed_work_submit(&ble_work, K_NO_WAIT);
		break;
	case BLE_ADV_START:
		ble_state = BLE_DISCONNECTED;
		break;
	case BLE_ADVERTISING:
		connect_canceled = true;
		k_delayed_work_submit(&ble_work, K_NO_WAIT);
		break;
	case BLE_CONNECT_CREATE:
		ble_state = BLE_CONNECT_CANCEL;
		/* Intentional fall-through */
	case BLE_CONNECTED:
		connect_canceled = true;
		k_delayed_work_submit(&ble_work, K_NO_WAIT);
		break;
	case BLE_CONNECT_CANCEL:
		break;
	}
}

static bool pong_uuid_match(const u8_t *data, u8_t len)
{
	while (len >= 16U) {
		if (!memcmp(data, pong_svc_uuid.val, 16)) {
			return true;
		}

		len -= 16U;
		data += 16;
	}

	return false;
}

static void create_conn(const bt_addr_le_t *addr)
{
	if (default_conn) {
		return;
	}

	printk("Found matching device, initiating connection...\n");

	default_conn = bt_conn_create_le(addr, BT_LE_CONN_PARAM_DEFAULT);
	if (!default_conn) {
		printk("Failed to initiate connection");
		return;
	}

	ble_state = BLE_CONNECT_CREATE;
	k_delayed_work_submit(&ble_work, SCAN_TIMEOUT);
}

static void device_found(const bt_addr_le_t *addr, s8_t rssi, u8_t type,
			 struct net_buf_simple *ad)
{
	if (type != BT_LE_ADV_IND) {
		return;
	}

	while (ad->len > 1) {
		u8_t len = net_buf_simple_pull_u8(ad);
		u8_t type;

		/* Check for early termination */
		if (len == 0U) {
			return;
		}

		if (len > ad->len) {
			printk("AD malformed\n");
			return;
		}

		type = net_buf_simple_pull_u8(ad);
		if (type == BT_DATA_UUID128_ALL &&
		    pong_uuid_match(ad->data, len - 1)) {
			bt_le_scan_stop();
			create_conn(addr);
			return;
		}

		net_buf_simple_pull(ad, len - 1);
	}
}

static u32_t adv_timeout(void)
{
	u32_t timeout;

	if (bt_rand(&timeout, sizeof(timeout)) < 0) {
		return K_SECONDS(10);
	}

	timeout %= K_SECONDS(10);

	return timeout + K_SECONDS(1);
}

static void cancel_connect(void)
{
	connect_canceled = false;

	switch (ble_state) {
	case BLE_SCAN:
		bt_le_scan_stop();
		break;
	case BLE_ADVERTISING:
		bt_le_adv_stop();
		break;
	case BLE_CONNECT_CREATE:
	case BLE_CONNECTED:
		bt_conn_disconnect(default_conn,
				   BT_HCI_ERR_REMOTE_USER_TERM_CONN);
		break;
	default:
		break;
	}

	/* For CONNECTED the state will be updated in the disconnected cb */
	if (ble_state != BLE_CONNECTED) {
		ble_state = BLE_DISCONNECTED;
	}
}

static void ble_timeout(struct k_work *work)
{
	int err;

	if (connect_canceled) {
		cancel_connect();
		return;
	}

	switch (ble_state) {
	case BLE_DISCONNECTED:
		break;
	case BLE_SCAN_START:
		err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
		if (err) {
			printk("Scanning failed to start (err %d)\n", err);
		}

		printk("Started scanning for devices\n");
		ble_state = BLE_SCAN;
		k_delayed_work_submit(&ble_work, SCAN_TIMEOUT);
		break;
	case BLE_CONNECT_CREATE:
		printk("Connection attempt timed out\n");
		bt_conn_disconnect(default_conn,
				   BT_HCI_ERR_REMOTE_USER_TERM_CONN);
		ble_state = BLE_ADV_START;
		k_delayed_work_submit(&ble_work, K_NO_WAIT);
		break;
	case BLE_SCAN:
		printk("No devices found during scan\n");
		bt_le_scan_stop();
		ble_state = BLE_ADV_START;
		k_delayed_work_submit(&ble_work, K_NO_WAIT);
		break;
	case BLE_ADV_START:
		err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad),
				      NULL, 0);
		if (err) {
			printk("Advertising failed to start (err %d)\n", err);
			return;
		}

		printk("Advertising successfully started\n");
		ble_state = BLE_ADVERTISING;
		k_delayed_work_submit(&ble_work, adv_timeout());
		break;
	case BLE_ADVERTISING:
		printk("Timed out advertising\n");
		bt_le_adv_stop();
		ble_state = BLE_SCAN_START;
		k_delayed_work_submit(&ble_work, K_NO_WAIT);
		break;
	case BLE_CONNECTED:
		discov_param.uuid = &pong_svc_uuid.uuid;
		discov_param.func = discover_func;
		discov_param.start_handle = 0x0001;
		discov_param.end_handle = 0xffff;
		discov_param.type = BT_GATT_DISCOVER_PRIMARY;

		err = bt_gatt_discover(default_conn, &discov_param);
		if (err) {
			printk("Discover failed (err %d)\n", err);
			return;
		}
		break;
	case BLE_CONNECT_CANCEL:
		break;
	}
}

static struct bt_gatt_ccc_cfg pong_ccc_cfg[BT_GATT_CCC_MAX];

static void pong_ccc_cfg_changed(const struct bt_gatt_attr *attr, u16_t val)
{
	printk("val %u\n", val);

	remote_ready = (val == BT_GATT_CCC_NOTIFY);

	if (remote_ready && remote_handle) {
		pong_conn_ready(initiator);
	}
}

static struct bt_gatt_attr pong_attrs[] = {
	/* Vendor Primary Service Declaration */
	BT_GATT_PRIMARY_SERVICE(&pong_svc_uuid.uuid),
	BT_GATT_CHARACTERISTIC(&pong_chr_uuid.uuid, BT_GATT_CHRC_NOTIFY,
			       BT_GATT_PERM_NONE, NULL, NULL, NULL),
	BT_GATT_CCC(pong_ccc_cfg, pong_ccc_cfg_changed),
};

static struct bt_gatt_service pong_svc = BT_GATT_SERVICE(pong_attrs);

void ble_init(void)
{
	int err;

	err = bt_enable(NULL);
	if (err) {
		printk("Enabling Bluetooth failed (err %d)\n", err);
		return;
	}

	k_delayed_work_init(&ble_work, ble_timeout);

	bt_conn_cb_register(&conn_callbacks);


	local_attr = &pong_attrs[1];
	bt_gatt_service_register(&pong_svc);
}
