/** @file
 *  @brief Bluetooth Telephone Bearer Service shell
 */

/*
 * Copyright (c) 2020-2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <zephyr/zephyr.h>
#include <zephyr/shell/shell.h>

#include <zephyr/bluetooth/audio/tbs.h>

#include "bt.h"

static struct bt_conn *tbs_authorized_conn;
static bool cbs_registered;

static bool tbs_authorize_cb(struct bt_conn *conn)
{
	return conn == tbs_authorized_conn;
}

static bool tbs_originate_call_cb(struct bt_conn *conn, uint8_t call_index,
				  const char *uri)
{
	/* Always accept calls */
	return true;
}

static struct bt_tbs_cb tbs_cbs = {
	.originate_call = tbs_originate_call_cb,
	.authorize = tbs_authorize_cb
};

static int cmd_tbs_authorize(const struct shell *sh, size_t argc, char *argv[])
{
	char addr[BT_ADDR_LE_STR_LEN];

	tbs_authorized_conn = default_conn;

	(void)bt_addr_le_to_str(bt_conn_get_dst(tbs_authorized_conn),
				addr, sizeof(addr));

	shell_print(sh, "Connection with addr %s authorized", addr);

	return 0;
}

static int cmd_tbs_init(void)
{
	if (!cbs_registered) {
		bt_tbs_register_cb(&tbs_cbs);
		cbs_registered = true;
	}

	return 0;
}

static int cmd_tbs_accept(const struct shell *sh, size_t argc, char *argv[])
{
	long call_index;
	int result;

	call_index = strtol(argv[1], NULL, 0);
	if (call_index <= 0 || call_index > UINT8_MAX) {
		shell_error(sh, "Invalid call_index: %ld", call_index);
		return -ENOEXEC;
	}

	result = bt_tbs_accept((uint8_t)call_index);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS succeeded for call_index: %ld",
			    call_index);
	}

	return result;
}

static int cmd_tbs_terminate(const struct shell *sh, size_t argc,
			     char *argv[])
{
	long call_index;
	int result;

	call_index = strtol(argv[1], NULL, 0);
	if (call_index <= 0 || call_index > UINT8_MAX) {
		shell_error(sh, "Invalid call_index: %ld", call_index);
		return -ENOEXEC;
	}

	result = bt_tbs_terminate((uint8_t)call_index);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS succeeded for call_index: %ld",
			    call_index);
	}

	return result;
}

static int cmd_tbs_hold(const struct shell *sh, size_t argc, char *argv[])
{
	long call_index;
	int result;

	call_index = strtol(argv[1], NULL, 0);
	if (call_index <= 0 || call_index > UINT8_MAX) {
		shell_error(sh, "Invalid call_index: %ld", call_index);
		return -ENOEXEC;
	}

	result = bt_tbs_hold((uint8_t)call_index);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS succeeded for call_index: %ld",
			    call_index);
	}

	return result;
}

static int cmd_tbs_retrieve(const struct shell *sh, size_t argc,
			    char *argv[])
{
	long call_index;
	int result;

	call_index = strtol(argv[1], NULL, 0);
	if (call_index <= 0 || call_index > UINT8_MAX) {
		shell_error(sh, "Invalid call_index: %ld", call_index);
		return -ENOEXEC;
	}

	result = bt_tbs_retrieve((uint8_t)call_index);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS succeeded for call_index: %ld",
			    call_index);
	}

	return result;
}

static int cmd_tbs_originate(const struct shell *sh, size_t argc, char *argv[])
{
	long service_index;
	int result;
	uint8_t call_index;

	if (argc > 2) {
		service_index = strtol(argv[1], NULL, 0);
		if (service_index < 0 ||
		    service_index >= CONFIG_BT_TBS_BEARER_COUNT) {
			shell_error(sh, "Invalid service index: %ld",
				    service_index);

			return -ENOEXEC;
		}
	} else {
		service_index = 0;
	}

	result = bt_tbs_originate((uint8_t)service_index, argv[argc - 1],
				  &call_index);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS call_index %u originated", call_index);
	}

	return result;
}

static int cmd_tbs_join(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t call_indexes[CONFIG_BT_TBS_MAX_CALLS];
	int result;
	long call_index;

	for (int i = 1; i < argc; i++) {
		call_index = strtol(argv[i], NULL, 0);

		if (call_index < 0 || call_index > UINT8_MAX) {
			shell_error(sh, "Invalid call index %ld", call_index);
			return -ENOEXEC;
		}

		call_indexes[i - 1] = (uint8_t)call_index;
	}

	result = bt_tbs_join(argc - 1, call_indexes);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS join succeeded");
	}

	return result;
}

static int cmd_tbs_answer(const struct shell *sh, size_t argc, char *argv[])
{
	long call_index;
	int result;

	call_index = strtol(argv[1], NULL, 0);
	if (call_index <= 0 || call_index > UINT8_MAX) {
		shell_error(sh, "Invalid call_index: %ld", call_index);
		return -ENOEXEC;
	}

	result = bt_tbs_remote_answer((uint8_t)call_index);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS succeeded for call_index: %ld",
			    call_index);
	}

	return result;
}

static int cmd_tbs_remote_hold(const struct shell *sh, size_t argc,
			       char *argv[])
{
	long call_index;
	int result;

	call_index = strtol(argv[1], NULL, 0);
	if (call_index <= 0 || call_index > UINT8_MAX) {
		shell_error(sh, "Invalid call_index: %ld", call_index);
		return -ENOEXEC;
	}

	result = bt_tbs_remote_hold((uint8_t)call_index);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS succeeded for call_index: %ld",
			    call_index);
	}

	return result;
}

static int cmd_tbs_remote_retrieve(const struct shell *sh, size_t argc,
				   char *argv[])
{
	long call_index;
	int result;

	call_index = strtol(argv[1], NULL, 0);
	if (call_index <= 0 || call_index > UINT8_MAX) {
		shell_error(sh, "Invalid call_index: %ld", call_index);
		return -ENOEXEC;
	}

	result = bt_tbs_remote_retrieve((uint8_t)call_index);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS succeeded for call_index: %ld",
			    call_index);
	}

	return result;
}

static int cmd_tbs_remote_terminate(const struct shell *sh, size_t argc,
				    char *argv[])
{
	long call_index;
	int result;

	call_index = strtol(argv[1], NULL, 0);
	if (call_index <= 0 || call_index > UINT8_MAX) {
		shell_error(sh, "Invalid call_index: %ld", call_index);
		return -ENOEXEC;
	}

	result = bt_tbs_remote_terminate((uint8_t)call_index);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS succeeded for call_index: %ld",
			    call_index);
	}

	return result;
}

static int cmd_tbs_incoming(const struct shell *sh, size_t argc, char *argv[])
{
	long service_index;
	int result;

	if (argc > 4) {
		service_index = strtol(argv[1], NULL, 0);
		if (service_index < 0 ||
		    service_index >= CONFIG_BT_TBS_BEARER_COUNT) {
			shell_error(sh, "Invalid service index: %ld",
				    service_index);

			return -ENOEXEC;
		}
	} else {
		service_index = 0;
	}

	result = bt_tbs_remote_incoming((uint8_t)service_index,
					argv[argc - 3],
					argv[argc - 2],
					argv[argc - 1]);
	if (result < 0) {
		shell_print(sh, "TBS failed: %d", result);
	} else {
		shell_print(sh, "TBS succeeded");
	}

	return result;
}

static int cmd_tbs_set_bearer_provider_name(const struct shell *sh, size_t argc,
					    char *argv[])
{
	long service_index;
	int result;

	if (argc > 2) {
		if (!strcmp(argv[1], "gtbs")) {
			service_index = BT_TBS_GTBS_INDEX;
		} else {
			service_index = strtol(argv[1], NULL, 0);
			if (service_index < 0 ||
			    service_index >= CONFIG_BT_TBS_BEARER_COUNT) {
				shell_error(sh, "Invalid service index: %ld",
					    service_index);
				return -ENOEXEC;
			}
		}
	} else {
		service_index = 0;
	}

	result = bt_tbs_set_bearer_provider_name((uint8_t)service_index,
						 argv[argc - 1]);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "Could not set provider name: %d", result);
	}

	return result;
}

static int cmd_tbs_set_bearer_technology(const struct shell *sh, size_t argc,
					 char *argv[])
{
	long technology;
	long service_index;
	int result;

	if (argc > 2) {
		if (!strcmp(argv[1], "gtbs")) {
			service_index = BT_TBS_GTBS_INDEX;
		} else {
			service_index = strtol(argv[1], NULL, 0);
			if (service_index < 0 ||
			    service_index >= CONFIG_BT_TBS_BEARER_COUNT) {
				shell_error(sh, "Invalid service index: %ld",
					    service_index);
				return -ENOEXEC;
			}
		}
	} else {
		service_index = 0;
	}

	technology = strtol(argv[argc - 1], NULL, 0);
	if (technology < 0 || technology > UINT8_MAX) {
		shell_error(sh, "Invalid technology value: %ld", technology);

		return -ENOEXEC;
	}

	result = bt_tbs_set_bearer_technology((uint8_t)service_index,
					      (uint8_t)technology);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "Could not set technology: %d", result);
	}

	return result;
}

static int cmd_tbs_set_bearer_signal_strength(const struct shell *sh,
					      size_t argc, char *argv[])
{
	long signal_strength;
	long service_index;
	int result;

	if (argc > 2) {
		if (!strcmp(argv[1], "gtbs")) {
			service_index = BT_TBS_GTBS_INDEX;
		} else {
			service_index = strtol(argv[1], NULL, 0);
			if (service_index < 0 ||
			service_index >= CONFIG_BT_TBS_BEARER_COUNT) {
				shell_error(sh, "Invalid service index: %ld",
					    service_index);

				return -ENOEXEC;
			}
		}
	} else {
		service_index = 0;
	}

	signal_strength = strtol(argv[argc - 1], NULL, 0);
	if (signal_strength < 0 || signal_strength > UINT8_MAX) {
		shell_error(sh, "Invalid signal strength: %ld",
			    signal_strength);

		return -ENOEXEC;
	}

	result = bt_tbs_set_signal_strength((uint8_t)service_index,
					    (uint8_t)signal_strength);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "Could not set signal strength: %d", result);
	}

	return result;
}

static int cmd_tbs_set_status_flags(const struct shell *sh, size_t argc,
				    char *argv[])
{
	long status_flags;
	long service_index;
	int result;

	if (argc > 2) {
		if (!strcmp(argv[1], "gtbs")) {
			service_index = BT_TBS_GTBS_INDEX;
		} else {
			service_index = strtol(argv[1], NULL, 0);
			if (service_index < 0 ||
			    service_index >= CONFIG_BT_TBS_BEARER_COUNT) {
				shell_error(sh, "Invalid service index: %ld",
					    service_index);

				return -ENOEXEC;
			}
		}
	} else {
		service_index = 0;
	}

	status_flags = strtol(argv[argc - 1], NULL, 0);
	if (status_flags < 0 || status_flags > 3) {
		shell_error(sh, "Invalid status flags value: %ld",
			    status_flags);

		return -ENOEXEC;
	}

	result = bt_tbs_set_status_flags((uint8_t)service_index,
					 (uint16_t)status_flags);
	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "Could not set status flags: %d", result);
	}

	return result;
}

static int cmd_tbs_set_uri_scheme_list(const struct shell *sh, size_t argc,
				       char *argv[])
{
	long service_index;
	int result;

	service_index = strtol(argv[1], NULL, 0);
	if (service_index < 0 || service_index >= CONFIG_BT_TBS_BEARER_COUNT) {
		shell_error(sh, "Invalid service index: %ld", service_index);

		return -ENOEXEC;
	}

	result = bt_tbs_set_uri_scheme_list((uint8_t)service_index,
					    (const char **)&argv[2],
					    argc - 2);

	if (result != BT_TBS_RESULT_CODE_SUCCESS) {
		shell_print(sh, "Could not set URI prefix list: %d", result);
	}

	return result;
}

static int cmd_tbs_print_calls(const struct shell *sh, size_t argc,
			       char *argv[])
{
	if (IS_ENABLED(CONFIG_BT_DEBUG_TBS)) {
		bt_tbs_dbg_print_calls();
		return 0;
	}

	return -ENOEXEC;
}

static int cmd_tbs(const struct shell *sh, size_t argc, char **argv)
{
	if (argc > 1) {
		shell_error(sh, "%s unknown parameter: %s", argv[0],
			    argv[1]);
	} else {
		shell_error(sh, "%s Missing subcommand", argv[0]);
	}

	return -ENOEXEC;
}

SHELL_STATIC_SUBCMD_SET_CREATE(tbs_cmds,
	SHELL_CMD_ARG(init, NULL,
		      "Initialize TBS",
		      cmd_tbs_init, 1, 0),
	SHELL_CMD_ARG(authorize, NULL,
		      "Authorize the current connection",
		      cmd_tbs_authorize, 1, 0),
	SHELL_CMD_ARG(accept, NULL,
		      "Accept call <call_index>",
		      cmd_tbs_accept, 2, 0),
	SHELL_CMD_ARG(terminate, NULL,
		      "Terminate call <call_index>",
		      cmd_tbs_terminate, 2, 0),
	SHELL_CMD_ARG(hold, NULL,
		      "Hold call <call_index>",
		      cmd_tbs_hold, 2, 0),
	SHELL_CMD_ARG(retrieve, NULL,
		      "Retrieve call <call_index>",
		      cmd_tbs_retrieve, 2, 0),
	SHELL_CMD_ARG(originate, NULL,
		      "Originate call [<instance_index>] <uri>",
		      cmd_tbs_originate, 2, 1),
#if CONFIG_BT_TBS_MAX_CALLS > 1
	SHELL_CMD_ARG(join, NULL,
		      "Join calls <id> <id> [<id> [<id> [...]]]",
		      cmd_tbs_join, 3, CONFIG_BT_TBS_MAX_CALLS - 2),
#endif /* CONFIG_BT_TBS_MAX_CALLS > 1 */
	SHELL_CMD_ARG(incoming, NULL,
		      "Simulate incoming remote call "
		      "[<{instance_index, gtbs}>] <local_uri> <remote_uri> "
		      "<remote_friendly_name>",
		      cmd_tbs_incoming, 4, 1),
	SHELL_CMD_ARG(remote_answer, NULL,
		      "Simulate remote answer outgoing call <call_index>",
		      cmd_tbs_answer, 2, 0),
	SHELL_CMD_ARG(remote_retrieve, NULL,
		      "Simulate remote retrieve <call_index>",
		      cmd_tbs_remote_retrieve, 2, 0),
	SHELL_CMD_ARG(remote_terminate, NULL,
		      "Simulate remote terminate <call_index>",
		      cmd_tbs_remote_terminate, 2, 0),
	SHELL_CMD_ARG(remote_hold, NULL,
		      "Simulate remote hold <call_index>",
		      cmd_tbs_remote_hold, 2, 0),
	SHELL_CMD_ARG(set_bearer_provider_name, NULL,
		      "Set the bearer provider name [<{instance_index, gtbs}>] "
		      "<name>",
		      cmd_tbs_set_bearer_provider_name, 2, 1),
	SHELL_CMD_ARG(set_bearer_technology, NULL,
		      "Set the bearer technology [<{instance_index, gtbs}>] "
		      "<technology>",
		      cmd_tbs_set_bearer_technology, 2, 1),
	SHELL_CMD_ARG(set_bearer_signal_strength, NULL,
		      "Set the bearer signal strength "
		      "[<{instance_index, gtbs}>] <strength>",
		      cmd_tbs_set_bearer_signal_strength, 2, 1),
	SHELL_CMD_ARG(set_status_flags, NULL,
		      "Set the bearer feature and status value "
		      "[<{instance_index, gtbs}>] <feature_and_status>",
		      cmd_tbs_set_status_flags, 2, 1),
	SHELL_CMD_ARG(set_uri_scheme, NULL,
		      "Set the URI prefix list <bearer_idx> "
		      "<uri1 [uri2 [uri3 [...]]]>",
		      cmd_tbs_set_uri_scheme_list, 3, 30),
	SHELL_CMD_ARG(print_calls, NULL,
		      "Output all calls in the debug log",
		      cmd_tbs_print_calls, 1, 0),
	SHELL_SUBCMD_SET_END
);

SHELL_CMD_ARG_REGISTER(tbs, &tbs_cmds, "Bluetooth TBS shell commands",
		       cmd_tbs, 1, 1);
