/** @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/kernel.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_TBS_LOG_LEVEL_DBG)) {
		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);
