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


#include <tc_util.h>
#include <stdbool.h>
#include <zephyr.h>
#include <ztest.h>
#include <logging/log_backend.h>
#include <logging/log_ctrl.h>
#include <logging/log.h>

#define LOG_MODULE_NAME test
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

struct backend_context {
	uint32_t cnt;
	const char *exp_str[10];
	uint32_t delay;
	bool active;
	struct k_timer timer;
};

static int cbprintf_callback(int c, void *ctx)
{
	char **p = ctx;

	**p = c;
	(*p)++;

	return c;
}

static void backend_process(const struct log_backend *const backend,
			    union log_msg_generic *msg)
{
	char str[100];
	char *pstr = str;
	struct backend_context *context = (struct backend_context *)backend->cb->ctx;
	size_t len;
	uint8_t *p = log_msg_get_package(&msg->log, &len);

	(void)len;
	int slen = cbpprintf(cbprintf_callback, &pstr, p);

	str[slen] = '\0';

	zassert_equal(strcmp(str, context->exp_str[context->cnt]), 0,
			"Unexpected string %s (exp:%s)", str, context->exp_str[context->cnt]);

	context->cnt++;
}

static void expire_cb(struct k_timer *timer)
{
	void *ctx = k_timer_user_data_get(timer);
	struct backend_context *context = (struct backend_context *)ctx;

	context->active = true;
}

static void backend_init(const struct log_backend *const backend)
{
	struct backend_context *context = (struct backend_context *)backend->cb->ctx;

	k_timer_init(&context->timer, expire_cb, NULL);
	k_timer_user_data_set(&context->timer, (void *)context);
	k_timer_start(&context->timer, K_MSEC(context->delay), K_NO_WAIT);
}

static int backend_is_ready(const struct log_backend *const backend)
{
	struct backend_context *context = (struct backend_context *)backend->cb->ctx;

	return context->active ? 0 : -EBUSY;
}

static const struct log_backend_api backend_api = {
	.process = backend_process,
	.init = backend_init,
	.is_ready = backend_is_ready
};

static struct backend_context context1 = {
	.delay = 500
};

static struct backend_context context2 = {
	.delay = 1000,
};

LOG_BACKEND_DEFINE(backend1, backend_api, true, &context1);
LOG_BACKEND_DEFINE(backend2, backend_api, true, &context2);

/* Test is using two backends which are configured to be autostarted but have
 * prolonged initialization. Backend1 starts earlier.
 *
 * Logging does not process logs until at least one backend is ready so once
 * backend1 is ready first log message is processed. Since backend2 is not yet
 * ready it will not receive this message. Second message is created when
 * both backends are initialized so both receives the message.
 */
void test_log_backends_initialization(void)
{
	if (log_backend_count_get() != 2) {
		/* Other backends should not be enabled. */
		ztest_test_skip();
	}

	context1.cnt = 0;
	context2.cnt = 0;

	context1.exp_str[0] = "test1";
	context1.exp_str[1] = "test2";

	context2.exp_str[0] = "test2";

	LOG_INF("test1");

	/* Backends are not yet active. */
	zassert_false(context1.active, NULL);
	zassert_false(context2.active, NULL);

	k_msleep(context2.delay + 100);

	zassert_true(context1.active, NULL);
	zassert_true(context2.active, NULL);

	LOG_INF("test2");

	k_msleep(1100);

	/* Backend1 gets both messages but backend2 gets only second message
	 * because when first was processed it was not yet active.
	 */
	zassert_equal(context1.cnt, 2, "Unexpected value:%d (exp: %d)", context1.cnt, 2);
	zassert_equal(context2.cnt, 1, NULL);
}

void test_main(void)
{
	ztest_test_suite(test_log_backend_init,
			 ztest_unit_test(test_log_backends_initialization)
			 );
	ztest_run_test_suite(test_log_backend_init);
}
