/**
 * @file
 * @brief Shell APIs for Bluetooth CSIS
 *
 * Copyright (c) 2020 Bose Corporation
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/types.h>

#include <zephyr.h>
#include <zephyr/types.h>
#include <shell/shell.h>
#include <stdlib.h>
#include <bluetooth/gatt.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/audio/csis.h>
#include "bt.h"

extern const struct shell *ctx_shell;
static struct bt_csis *csis;
static uint8_t sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_ACCEPT;

static void locked_cb(struct bt_conn *conn, struct bt_csis *csis, bool locked)
{
	if (conn == NULL) {
		shell_error(ctx_shell, "Server %s the device",
			    locked ? "locked" : "released");
	} else {
		char addr[BT_ADDR_LE_STR_LEN];

		conn_addr_str(conn, addr, sizeof(addr));

		shell_print(ctx_shell, "Client %s %s the device",
			    addr, locked ? "locked" : "released");
	}
}

static uint8_t sirk_read_req_cb(struct bt_conn *conn, struct bt_csis *csis)
{
	char addr[BT_ADDR_LE_STR_LEN];
	static const char *const rsp_strings[] = {
		"Accept", "Accept Enc", "Reject", "OOB only"
	};

	conn_addr_str(conn, addr, sizeof(addr));

	shell_print(ctx_shell, "Client %s requested to read the sirk. "
		    "Responding with %s", addr, rsp_strings[sirk_read_rsp]);

	return sirk_read_rsp;
}

struct bt_csis_cb csis_cbs = {
	.lock_changed = locked_cb,
	.sirk_read_req = sirk_read_req_cb,
};

static int cmd_csis_register(const struct shell *sh, size_t argc, char **argv)
{
	int err;
	struct bt_csis_register_param param = {
		.set_size = 2,
		.rank = 1,
		.lockable = true,
		/* Using the CSIS test sample SIRK */
		.set_sirk = { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce,
			      0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 },
		.cb = &csis_cbs
	};

	for (size_t argn = 1; argn < argc; argn++) {
		const char *arg = argv[argn];

		if (strcmp(arg, "size") == 0) {
			param.set_size = strtol(argv[++argn], NULL, 10);
		} else if (strcmp(arg, "rank") == 0) {
			param.rank = strtol(argv[++argn], NULL, 10);
		} else if (strcmp(arg, "not-lockable") == 0) {
			param.lockable = false;
		} else if (strcmp(arg, "sirk") == 0) {
			size_t len;

			argn++;
			len = hex2bin(argv[argn], strlen(argv[argn]),
				      param.set_sirk, sizeof(param.set_sirk));
			if (len == 0) {
				shell_error(sh, "Could not parse SIRK");
				return -ENOEXEC;
			}
		} else {
			shell_help(sh);
			return SHELL_CMD_HELP_PRINTED;
		}
	}

	err = bt_csis_register(&param, &csis);
	if (err != 0) {
		shell_error(sh, "Could not register CSIS: %d", err);
		return err;
	}

	return 0;
}

static int cmd_csis_advertise(const struct shell *sh, size_t argc,
			      char *argv[])
{
	int err;

	if (strcmp(argv[1], "off") == 0) {
		err = bt_csis_advertise(csis, false);
		if (err != 0) {
			shell_error(sh, "Failed to stop advertising %d", err);
			return -ENOEXEC;
		}
		shell_print(sh, "Advertising stopped");
	} else if (strcmp(argv[1], "on") == 0) {
		err = bt_csis_advertise(csis, true);
		if (err != 0) {
			shell_error(sh, "Failed to start advertising %d", err);
			return -ENOEXEC;
		}
		shell_print(sh, "Advertising started");
	} else {
		shell_error(sh, "Invalid argument: %s", argv[1]);
		return -ENOEXEC;
	}

	return 0;
}

static int cmd_csis_update_psri(const struct shell *sh, size_t argc,
				char *argv[])
{
	int err;

	if (bt_csis_advertise(csis, false) != 0) {
		shell_error(sh,
			    "Failed to stop advertising - psri not updated");
		return -ENOEXEC;
	}
	err = bt_csis_advertise(csis, true);
	if (err != 0) {
		shell_error(sh,
			    "Failed to start advertising  - psri not updated");
		return -ENOEXEC;
	}

	shell_print(sh, "PSRI and optionally RPA updated");

	return 0;
}

static int cmd_csis_print_sirk(const struct shell *sh, size_t argc,
			       char *argv[])
{
	bt_csis_print_sirk(csis);
	return 0;
}

static int cmd_csis_lock(const struct shell *sh, size_t argc, char *argv[])
{
	int err;

	err = bt_csis_lock(csis, true, false);
	if (err != 0) {
		shell_error(sh, "Failed to set lock: %d", err);
		return -ENOEXEC;
	}

	shell_print(sh, "Set locked");

	return 0;
}

static int cmd_csis_release(const struct shell *sh, size_t argc,
			    char *argv[])
{
	bool force = false;
	int err;

	if (argc > 1) {
		if (strcmp(argv[1], "force") == 0) {
			force = true;
		} else {
			shell_error(sh, "Unknown parameter: %s", argv[1]);
			return -ENOEXEC;
		}
	}

	err = bt_csis_lock(csis, false, force);

	if (err != 0) {
		shell_error(sh, "Failed to release lock: %d", err);
		return -ENOEXEC;
	}

	shell_print(sh, "Set released");

	return 0;
}

static int cmd_csis_set_sirk_rsp(const struct shell *sh, size_t argc,
				 char *argv[])
{
	if (strcmp(argv[1], "accept") == 0) {
		sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_ACCEPT;
	} else if (strcmp(argv[1], "accept_enc") == 0) {
		sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_ACCEPT_ENC;
	} else if (strcmp(argv[1], "reject") == 0) {
		sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_REJECT;
	} else if (strcmp(argv[1], "oob") == 0) {
		sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_OOB_ONLY;
	} else {
		shell_error(sh, "Unknown parameter: %s", argv[1]);
		return -ENOEXEC;
	}

	return 0;
}

static int cmd_csis(const struct shell *sh, size_t argc, char **argv)
{
	shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]);

	return -ENOEXEC;
}

SHELL_STATIC_SUBCMD_SET_CREATE(csis_cmds,
	SHELL_CMD_ARG(register, NULL,
		      "Initialize the service and register callbacks "
		      "[size <int>] [rank <int>] [not-lockable] [sirk <data>]",
		      cmd_csis_register, 1, 4),
	SHELL_CMD_ARG(advertise, NULL,
		      "Start/stop advertising CSIS PSRIs <on/off>",
		      cmd_csis_advertise, 2, 0),
	SHELL_CMD_ARG(update_psri, NULL,
		      "Update the advertised PSRI",
		      cmd_csis_update_psri, 1, 0),
	SHELL_CMD_ARG(lock, NULL,
		      "Lock the set",
		      cmd_csis_lock, 1, 0),
	SHELL_CMD_ARG(release, NULL,
		      "Release the set [force]",
		      cmd_csis_release, 1, 1),
	SHELL_CMD_ARG(print_sirk, NULL,
		      "Print the currently used SIRK",
		      cmd_csis_print_sirk, 1, 0),
	SHELL_CMD_ARG(set_sirk_rsp, NULL,
		      "Set the response used in SIRK requests "
		      "<accept, accept_enc, reject, oob>",
		      cmd_csis_set_sirk_rsp, 2, 0),
		      SHELL_SUBCMD_SET_END
);

SHELL_CMD_ARG_REGISTER(csis, &csis_cmds, "Bluetooth CSIS shell commands",
		       cmd_csis, 1, 1);
