/*
 * Shell backend used for testing
 *
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/shell/shell_dummy.h>
#include <zephyr/init.h>

SHELL_DUMMY_DEFINE(shell_transport_dummy);
SHELL_DEFINE(shell_dummy, CONFIG_SHELL_PROMPT_DUMMY, &shell_transport_dummy, 256,
	     0, SHELL_FLAG_OLF_CRLF);

static int init(const struct shell_transport *transport,
		const void *config,
		shell_transport_handler_t evt_handler,
		void *context)
{
	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;

	if (sh_dummy->initialized) {
		return -EINVAL;
	}

	sh_dummy->initialized = true;

	return 0;
}

static int uninit(const struct shell_transport *transport)
{
	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;

	if (!sh_dummy->initialized) {
		return -ENODEV;
	}

	sh_dummy->initialized = false;

	return 0;
}

static int enable(const struct shell_transport *transport, bool blocking)
{
	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;

	if (!sh_dummy->initialized) {
		return -ENODEV;
	}

	return 0;
}

static int write(const struct shell_transport *transport,
		 const void *data, size_t length, size_t *cnt)
{
	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;
	size_t store_cnt;

	if (!sh_dummy->initialized) {
		*cnt = 0;
		return -ENODEV;
	}

	store_cnt = length;
	if (sh_dummy->len + store_cnt >= sizeof(sh_dummy->buf)) {
		store_cnt = sizeof(sh_dummy->buf) - sh_dummy->len - 1;
	}
	memcpy(sh_dummy->buf + sh_dummy->len, data, store_cnt);
	sh_dummy->len += store_cnt;

	*cnt = length;

	return 0;
}

static int read(const struct shell_transport *transport,
		void *data, size_t length, size_t *cnt)
{
	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;

	if (!sh_dummy->initialized) {
		return -ENODEV;
	}

	*cnt = 0;

	return 0;
}

const struct shell_transport_api shell_dummy_transport_api = {
	.init = init,
	.uninit = uninit,
	.enable = enable,
	.write = write,
	.read = read
};

static int enable_shell_dummy(const struct device *arg)
{
	ARG_UNUSED(arg);
	static const struct shell_backend_config_flags cfg_flags =
					SHELL_DEFAULT_BACKEND_CONFIG_FLAGS;
	shell_init(&shell_dummy, NULL, cfg_flags, true, LOG_LEVEL_INF);
	return 0;
}
SYS_INIT(enable_shell_dummy, POST_KERNEL, 0);

const struct shell *shell_backend_dummy_get_ptr(void)
{
	return &shell_dummy;
}

const char *shell_backend_dummy_get_output(const struct shell *shell,
					   size_t *sizep)
{
	struct shell_dummy *sh_dummy = (struct shell_dummy *)shell->iface->ctx;

	sh_dummy->buf[sh_dummy->len] = '\0';
	*sizep = sh_dummy->len;
	sh_dummy->len = 0;

	return sh_dummy->buf;
}

void shell_backend_dummy_clear_output(const struct shell *shell)
{
	struct shell_dummy *sh_dummy = (struct shell_dummy *)shell->iface->ctx;

	sh_dummy->buf[0] = '\0';
	sh_dummy->len = 0;
}
