/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/logging/log.h>
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_ctrl.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_internal.h>
#include <zephyr/sys/mpsc_pbuf.h>
#include <zephyr/logging/log_link.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys_clock.h>
#include <zephyr/init.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/iterable_sections.h>
#include <ctype.h>
#include <zephyr/logging/log_frontend.h>
#include <zephyr/internal/syscall_handler.h>
#include <zephyr/logging/log_output_dict.h>
#include <zephyr/logging/log_output_custom.h>
#include <zephyr/linker/utils.h>

#ifdef CONFIG_LOG_TIMESTAMP_USE_REALTIME
#include <zephyr/posix/time.h>
#endif

LOG_MODULE_REGISTER(log);

#ifndef CONFIG_LOG_PROCESS_THREAD_SLEEP_MS
#define CONFIG_LOG_PROCESS_THREAD_SLEEP_MS 0
#endif

#ifndef CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD
#define CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD 0
#endif

#ifndef CONFIG_LOG_PROCESS_THREAD_STACK_SIZE
#define CONFIG_LOG_PROCESS_THREAD_STACK_SIZE 1
#endif

#ifndef CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS
#define CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS 0
#endif

#ifndef CONFIG_LOG_PROCESSING_LATENCY_US
#define CONFIG_LOG_PROCESSING_LATENCY_US 0
#endif

#ifndef CONFIG_LOG_BUFFER_SIZE
#define CONFIG_LOG_BUFFER_SIZE 4
#endif

#ifdef CONFIG_LOG_PROCESS_THREAD_CUSTOM_PRIORITY
#define LOG_PROCESS_THREAD_PRIORITY CONFIG_LOG_PROCESS_THREAD_PRIORITY
#else
#define LOG_PROCESS_THREAD_PRIORITY K_LOWEST_APPLICATION_THREAD_PRIO
#endif

#ifndef CONFIG_LOG_TAG_MAX_LEN
#define CONFIG_LOG_TAG_MAX_LEN 0
#endif

#ifndef CONFIG_LOG_FAILURE_REPORT_PERIOD
#define CONFIG_LOG_FAILURE_REPORT_PERIOD 0
#endif

#ifndef CONFIG_LOG_ALWAYS_RUNTIME
BUILD_ASSERT(!IS_ENABLED(CONFIG_NO_OPTIMIZATIONS),
	     "CONFIG_LOG_ALWAYS_RUNTIME must be enabled when "
	     "CONFIG_NO_OPTIMIZATIONS is set");
BUILD_ASSERT(!IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE),
	     "CONFIG_LOG_ALWAYS_RUNTIME must be enabled when "
	     "CONFIG_LOG_MODE_IMMEDIATE is set");
#endif

static const log_format_func_t format_table[] = {
	[LOG_OUTPUT_TEXT] = IS_ENABLED(CONFIG_LOG_OUTPUT) ?
						log_output_msg_process : NULL,
	[LOG_OUTPUT_SYST] = IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) ?
						log_output_msg_syst_process : NULL,
	[LOG_OUTPUT_DICT] = IS_ENABLED(CONFIG_LOG_DICTIONARY_SUPPORT) ?
						log_dict_output_msg_process : NULL,
	[LOG_OUTPUT_CUSTOM] = IS_ENABLED(CONFIG_LOG_CUSTOM_FORMAT_SUPPORT) ?
						log_custom_output_msg_process : NULL,
};

log_format_func_t log_format_func_t_get(uint32_t log_type)
{
	return format_table[log_type];
}

size_t log_format_table_size(void)
{
	return ARRAY_SIZE(format_table);
}

K_SEM_DEFINE(log_process_thread_sem, 0, 1);

static atomic_t initialized;
static bool panic_mode;
static bool backend_attached;
static atomic_t buffered_cnt;
static atomic_t dropped_cnt;
static k_tid_t proc_tid;
static struct k_timer log_process_thread_timer;

static log_timestamp_t dummy_timestamp(void);
static log_timestamp_get_t timestamp_func = dummy_timestamp;
static uint32_t timestamp_freq;
static log_timestamp_t proc_latency;
static log_timestamp_t prev_timestamp;
static atomic_t unordered_cnt;
static uint64_t last_failure_report;

static STRUCT_SECTION_ITERABLE(log_msg_ptr, log_msg_ptr);
static STRUCT_SECTION_ITERABLE_ALTERNATE(log_mpsc_pbuf, mpsc_pbuf_buffer, log_buffer);
static struct mpsc_pbuf_buffer *curr_log_buffer;

#ifdef CONFIG_MPSC_PBUF
static uint32_t __aligned(Z_LOG_MSG_ALIGNMENT)
	buf32[CONFIG_LOG_BUFFER_SIZE / sizeof(int)];

static void z_log_notify_drop(const struct mpsc_pbuf_buffer *buffer,
			      const union mpsc_pbuf_generic *item);

static const struct mpsc_pbuf_buffer_config mpsc_config = {
	.buf = (uint32_t *)buf32,
	.size = ARRAY_SIZE(buf32),
	.notify_drop = z_log_notify_drop,
	.get_wlen = log_msg_generic_get_wlen,
	.flags = (IS_ENABLED(CONFIG_LOG_MODE_OVERFLOW) ?
		  MPSC_PBUF_MODE_OVERWRITE : 0) |
		 (IS_ENABLED(CONFIG_LOG_MEM_UTILIZATION) ?
		  MPSC_PBUF_MAX_UTILIZATION : 0)
};
#endif

/* Check that default tag can fit in tag buffer. */
COND_CODE_0(CONFIG_LOG_TAG_MAX_LEN, (),
	(BUILD_ASSERT(sizeof(CONFIG_LOG_TAG_DEFAULT) <= CONFIG_LOG_TAG_MAX_LEN + 1,
		      "Default string longer than tag capacity")));

static char tag[CONFIG_LOG_TAG_MAX_LEN + 1] =
	COND_CODE_0(CONFIG_LOG_TAG_MAX_LEN, ({}), (CONFIG_LOG_TAG_DEFAULT));

static void msg_process(union log_msg_generic *msg);

static log_timestamp_t dummy_timestamp(void)
{
	return 0;
}

log_timestamp_t z_log_timestamp(void)
{
	return timestamp_func();
}

static void z_log_msg_post_finalize(void)
{
	atomic_val_t cnt = atomic_inc(&buffered_cnt);

	if (panic_mode) {
		static struct k_spinlock process_lock;
		k_spinlock_key_t key = k_spin_lock(&process_lock);
		(void)log_process();

		k_spin_unlock(&process_lock, key);
	} else if (proc_tid != NULL) {
		/*
		 * If CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD == 1,
		 * timer is never needed. We release the processing
		 * thread after every message is posted.
		 */
		if (CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD == 1) {
			if (cnt == 0) {
				k_sem_give(&log_process_thread_sem);
			}
		} else {
			if (cnt == 0) {
				k_timer_start(&log_process_thread_timer,
					      K_MSEC(CONFIG_LOG_PROCESS_THREAD_SLEEP_MS),
					      K_NO_WAIT);
			} else if (CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD &&
				   (cnt + 1) == CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD) {
				k_timer_stop(&log_process_thread_timer);
				k_sem_give(&log_process_thread_sem);
			} else {
				/* No action needed. Message processing will be triggered by the
				 * timeout or when number of upcoming messages exceeds the
				 * threshold.
				 */
			}
		}
	}
}

const struct log_backend *log_format_set_all_active_backends(size_t log_type)
{
	const struct log_backend *failed_backend = NULL;

	STRUCT_SECTION_FOREACH(log_backend, backend) {
		if (log_backend_is_active(backend)) {
			int retCode = log_backend_format_set(backend, log_type);

			if (retCode != 0) {
				failed_backend = backend;
			}
		}
	}
	return failed_backend;
}

void z_log_vprintk(const char *fmt, va_list ap)
{
	if (!IS_ENABLED(CONFIG_LOG_PRINTK)) {
		return;
	}

	z_log_msg_runtime_vcreate(Z_LOG_LOCAL_DOMAIN_ID, NULL,
				   LOG_LEVEL_INTERNAL_RAW_STRING, NULL, 0,
				   Z_LOG_MSG_CBPRINTF_FLAGS(0),
				   fmt, ap);
}

#ifndef CONFIG_LOG_TIMESTAMP_USE_REALTIME
static log_timestamp_t default_get_timestamp(void)
{
	return IS_ENABLED(CONFIG_LOG_TIMESTAMP_64BIT) ?
		sys_clock_tick_get() : k_cycle_get_32();
}

static log_timestamp_t default_lf_get_timestamp(void)
{
	return IS_ENABLED(CONFIG_LOG_TIMESTAMP_64BIT) ?
		k_uptime_get() : k_uptime_get_32();
}
#else
static log_timestamp_t default_rt_get_timestamp(void)
{
	struct timespec tspec;

	clock_gettime(CLOCK_REALTIME, &tspec);

	return ((uint64_t)tspec.tv_sec * MSEC_PER_SEC) + (tspec.tv_nsec / NSEC_PER_MSEC);
}
#endif /* CONFIG_LOG_TIMESTAMP_USE_REALTIME */

void log_core_init(void)
{
	panic_mode = false;
	dropped_cnt = 0;
	buffered_cnt = 0;

	if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
		log_frontend_init();

		for (uint16_t s = 0; s < log_src_cnt_get(0); s++) {
			log_frontend_filter_set(s, CONFIG_LOG_MAX_LEVEL);
		}

		if (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY)) {
			return;
		}
	}

	/* Set default timestamp. */
#ifdef CONFIG_LOG_TIMESTAMP_USE_REALTIME
	log_set_timestamp_func(default_rt_get_timestamp, 1000U);
#else
	if (sys_clock_hw_cycles_per_sec() > 1000000) {
		log_set_timestamp_func(default_lf_get_timestamp, 1000U);
	} else {
		uint32_t freq = IS_ENABLED(CONFIG_LOG_TIMESTAMP_64BIT) ?
			CONFIG_SYS_CLOCK_TICKS_PER_SEC : sys_clock_hw_cycles_per_sec();
		log_set_timestamp_func(default_get_timestamp, freq);
	}
#endif /* CONFIG_LOG_TIMESTAMP_USE_REALTIME */

	if (IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
		z_log_msg_init();
	}

	if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
		z_log_runtime_filters_init();
	}
}

static uint32_t activate_foreach_backend(uint32_t mask)
{
	uint32_t mask_cpy = mask;

	while (mask_cpy) {
		uint32_t i = __builtin_ctz(mask_cpy);
		const struct log_backend *backend = log_backend_get(i);

		mask_cpy &= ~BIT(i);
		if (backend->autostart && (log_backend_is_ready(backend) == 0)) {
			mask &= ~BIT(i);
			log_backend_enable(backend,
					   backend->cb->ctx,
					   CONFIG_LOG_MAX_LEVEL);
		}
	}

	return mask;
}

static uint32_t z_log_init(bool blocking, bool can_sleep)
{
	uint32_t mask = 0;

	if (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY)) {
		return 0;
	}

	__ASSERT_NO_MSG(log_backend_count_get() < LOG_FILTERS_MAX_BACKENDS);

	if (atomic_inc(&initialized) != 0) {
		return 0;
	}

	int i = 0;
	if (IS_ENABLED(CONFIG_LOG_MULTIDOMAIN)) {
		z_log_links_initiate();
	}


	/* Assign ids to backends. */
	STRUCT_SECTION_FOREACH(log_backend, backend) {
		if (backend->autostart) {
			log_backend_init(backend);

			/* If backend has activation function then backend is
			 * not ready until activated.
			 */
			if (log_backend_is_ready(backend) == 0) {
				log_backend_enable(backend,
						   backend->cb->ctx,
						   CONFIG_LOG_MAX_LEVEL);
			} else {
				mask |= BIT(i);
			}

			i++;
		}
	}

	/* If blocking init, wait until all backends are activated. */
	if (blocking) {
		while (mask) {
			mask = activate_foreach_backend(mask);
			if (IS_ENABLED(CONFIG_MULTITHREADING) && can_sleep) {
				k_msleep(10);
			}
		}
	}

	return mask;
}

void log_init(void)
{
	(void)z_log_init(true, true);
}

static void thread_set(k_tid_t process_tid)
{
	proc_tid = process_tid;

	if (IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) {
		return;
	}

	if (CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD &&
	    process_tid &&
	    buffered_cnt >= CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD) {
		k_sem_give(&log_process_thread_sem);
	}
}

void log_thread_set(k_tid_t process_tid)
{
	if (IS_ENABLED(CONFIG_LOG_PROCESS_THREAD)) {
		__ASSERT_NO_MSG(0);
	} else {
		thread_set(process_tid);
	}
}

int log_set_timestamp_func(log_timestamp_get_t timestamp_getter, uint32_t freq)
{
	if (timestamp_getter == NULL) {
		return -EINVAL;
	}

	timestamp_func = timestamp_getter;
	timestamp_freq = freq;
	if (CONFIG_LOG_PROCESSING_LATENCY_US) {
		proc_latency = (freq * CONFIG_LOG_PROCESSING_LATENCY_US) / 1000000;
	}

	if (IS_ENABLED(CONFIG_LOG_OUTPUT)) {
		log_output_timestamp_freq_set(freq);
	}

	return 0;
}

void z_impl_log_panic(void)
{
	if (panic_mode) {
		return;
	}

	/* If panic happened early logger might not be initialized.
	 * Forcing initialization of the logger and auto-starting backends.
	 */
	(void)z_log_init(true, false);

	if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
		log_frontend_panic();
		if (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY)) {
			goto out;
		}
	}

	STRUCT_SECTION_FOREACH(log_backend, backend) {
		if (log_backend_is_active(backend)) {
			log_backend_panic(backend);
		}
	}

	if (!IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) {
		/* Flush */
		while (log_process() == true) {
		}
	}

out:
	panic_mode = true;
}

#ifdef CONFIG_USERSPACE
void z_vrfy_log_panic(void)
{
	z_impl_log_panic();
}
#include <syscalls/log_panic_mrsh.c>
#endif

static bool msg_filter_check(struct log_backend const *backend,
			     union log_msg_generic *msg)
{
	if (!z_log_item_is_msg(msg)) {
		return true;
	}

	if (!IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
		return true;
	}

	uint32_t backend_level;
	uint8_t level;
	uint8_t domain_id;
	int16_t source_id;

	level = log_msg_get_level(&msg->log);
	domain_id = log_msg_get_domain(&msg->log);
	source_id = log_msg_get_source_id(&msg->log);

	/* Accept all non-logging messages. */
	if (level == LOG_LEVEL_NONE) {
		return true;
	}
	if (source_id >= 0) {
		backend_level = log_filter_get(backend, domain_id, source_id, true);

		return (level <= backend_level);
	} else {
		return true;
	}
}

static void msg_process(union log_msg_generic *msg)
{
	STRUCT_SECTION_FOREACH(log_backend, backend) {
		if (log_backend_is_active(backend) &&
		    msg_filter_check(backend, msg)) {
			log_backend_msg_process(backend, msg);
		}
	}
}

void dropped_notify(void)
{
	uint32_t dropped = z_log_dropped_read_and_clear();

	STRUCT_SECTION_FOREACH(log_backend, backend) {
		if (log_backend_is_active(backend)) {
			log_backend_dropped(backend, dropped);
		}
	}
}

void unordered_notify(void)
{
	uint32_t unordered = atomic_set(&unordered_cnt, 0);

	LOG_WRN("%d unordered messages since last report", unordered);
}

void z_log_notify_backend_enabled(void)
{
	/* Wakeup logger thread after attaching first backend. It might be
	 * blocked with log messages pending.
	 */
	if (IS_ENABLED(CONFIG_LOG_PROCESS_THREAD) && !backend_attached) {
		k_sem_give(&log_process_thread_sem);
	}

	backend_attached = true;
}

static inline bool z_log_unordered_pending(void)
{
	return IS_ENABLED(CONFIG_LOG_MULTIDOMAIN) && unordered_cnt;
}

bool z_impl_log_process(void)
{
	if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
		return false;
	}

	k_timeout_t backoff = K_NO_WAIT;
	union log_msg_generic *msg;

	if (!backend_attached) {
		return false;
	}

	msg = z_log_msg_claim(&backoff);

	if (msg) {
		atomic_dec(&buffered_cnt);
		msg_process(msg);
		z_log_msg_free(msg);
	} else if (CONFIG_LOG_PROCESSING_LATENCY_US > 0 && !K_TIMEOUT_EQ(backoff, K_NO_WAIT)) {
		/* If backoff is requested, it means that there are pending
		 * messages but they are too new and processing shall back off
		 * to allow arrival of newer messages from remote domains.
		 */
		k_timer_start(&log_process_thread_timer, backoff, K_NO_WAIT);

		return false;
	}

	if (IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
		bool dropped_pend = z_log_dropped_pending();
		bool unordered_pend = z_log_unordered_pending();

		if ((dropped_pend || unordered_pend) &&
		   (k_uptime_get() - last_failure_report) > CONFIG_LOG_FAILURE_REPORT_PERIOD) {
			if (dropped_pend) {
				dropped_notify();
			}

			if (unordered_pend) {
				unordered_notify();
			}
		}

		last_failure_report += CONFIG_LOG_FAILURE_REPORT_PERIOD;
	}

	return z_log_msg_pending();
}

#ifdef CONFIG_USERSPACE
bool z_vrfy_log_process(void)
{
	return z_impl_log_process();
}
#include <syscalls/log_process_mrsh.c>
#endif

uint32_t z_impl_log_buffered_cnt(void)
{
	return buffered_cnt;
}

#ifdef CONFIG_USERSPACE
uint32_t z_vrfy_log_buffered_cnt(void)
{
	return z_impl_log_buffered_cnt();
}
#include <syscalls/log_buffered_cnt_mrsh.c>
#endif

void z_log_dropped(bool buffered)
{
	atomic_inc(&dropped_cnt);
	if (buffered) {
		atomic_dec(&buffered_cnt);
	}
}

uint32_t z_log_dropped_read_and_clear(void)
{
	return atomic_set(&dropped_cnt, 0);
}

bool z_log_dropped_pending(void)
{
	return dropped_cnt > 0;
}

void z_log_msg_init(void)
{
#ifdef CONFIG_MPSC_PBUF
	mpsc_pbuf_init(&log_buffer, &mpsc_config);
	curr_log_buffer = &log_buffer;
#endif
}

static struct log_msg *msg_alloc(struct mpsc_pbuf_buffer *buffer, uint32_t wlen)
{
	if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
		return NULL;
	}

	return (struct log_msg *)mpsc_pbuf_alloc(
		buffer, wlen,
		(CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS == -1)
			? K_FOREVER
			: K_MSEC(CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS));
}

struct log_msg *z_log_msg_alloc(uint32_t wlen)
{
	return msg_alloc(&log_buffer, wlen);
}

static void msg_commit(struct mpsc_pbuf_buffer *buffer, struct log_msg *msg)
{
	union log_msg_generic *m = (union log_msg_generic *)msg;

	if (IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) {
		msg_process(m);

		return;
	}

#ifdef CONFIG_MPSC_PBUF
	mpsc_pbuf_commit(buffer, &m->buf);
#endif
	z_log_msg_post_finalize();
}

void z_log_msg_commit(struct log_msg *msg)
{
	msg->hdr.timestamp = timestamp_func();
	msg_commit(&log_buffer, msg);
}

union log_msg_generic *z_log_msg_local_claim(void)
{
#ifdef CONFIG_MPSC_PBUF
	return (union log_msg_generic *)mpsc_pbuf_claim(&log_buffer);
#else
	return NULL;
#endif

}

/* If there are buffers dedicated for each link, claim the oldest message (lowest timestamp). */
union log_msg_generic *z_log_msg_claim_oldest(k_timeout_t *backoff)
{
	union log_msg_generic *msg = NULL;
	struct log_msg_ptr *chosen;
	log_timestamp_t t_min = sizeof(log_timestamp_t) > sizeof(uint32_t) ?
				UINT64_MAX : UINT32_MAX;
	int i = 0;

	/* Else iterate on all available buffers and get the oldest message. */
	STRUCT_SECTION_FOREACH(log_msg_ptr, msg_ptr) {
		struct log_mpsc_pbuf *buf;

		STRUCT_SECTION_GET(log_mpsc_pbuf, i, &buf);

#ifdef CONFIG_MPSC_PBUF
		if (msg_ptr->msg == NULL) {
			msg_ptr->msg = (union log_msg_generic *)mpsc_pbuf_claim(&buf->buf);
		}
#endif

		if (msg_ptr->msg) {
			log_timestamp_t t = log_msg_get_timestamp(&msg_ptr->msg->log);

			if (t < t_min) {
				t_min = t;
				msg = msg_ptr->msg;
				chosen = msg_ptr;
				curr_log_buffer = &buf->buf;
			}
		}
		i++;
	}

	if (msg) {
		if (CONFIG_LOG_PROCESSING_LATENCY_US > 0) {
			int32_t diff = t_min - (timestamp_func() - proc_latency);

			if (diff > 0) {
			       /* Entry is too new. Back off for sometime to allow new
				* remote messages to arrive which may have been captured
				* earlier (but on other platform). Calculate for how
				* long processing shall back off.
				*/
				if (timestamp_freq == sys_clock_hw_cycles_per_sec()) {
					*backoff = K_TICKS(diff);
				} else {
					*backoff = K_TICKS((diff * sys_clock_hw_cycles_per_sec()) /
							timestamp_freq);
				}

				return NULL;
			}
		}

		(*chosen).msg = NULL;
	}

	if (t_min < prev_timestamp) {
		atomic_inc(&unordered_cnt);
	}

	prev_timestamp = t_min;

	return msg;
}

union log_msg_generic *z_log_msg_claim(k_timeout_t *backoff)
{
	size_t len;

	STRUCT_SECTION_COUNT(log_mpsc_pbuf, &len);

	/* Use only one buffer if others are not registered. */
	if (IS_ENABLED(CONFIG_LOG_MULTIDOMAIN) && len > 1) {
		return z_log_msg_claim_oldest(backoff);
	}

	return z_log_msg_local_claim();
}

static void msg_free(struct mpsc_pbuf_buffer *buffer, const union log_msg_generic *msg)
{
#ifdef CONFIG_MPSC_PBUF
	mpsc_pbuf_free(buffer, &msg->buf);
#endif
}

void z_log_msg_free(union log_msg_generic *msg)
{
	msg_free(curr_log_buffer, msg);
}

static bool msg_pending(struct mpsc_pbuf_buffer *buffer)
{
#ifdef CONFIG_MPSC_PBUF
	return mpsc_pbuf_is_pending(buffer);
#else
	return false;
#endif
}

bool z_log_msg_pending(void)
{
	size_t len;
	int i = 0;

	STRUCT_SECTION_COUNT(log_mpsc_pbuf, &len);

	if (!IS_ENABLED(CONFIG_LOG_MULTIDOMAIN) || (len == 1)) {
		return msg_pending(&log_buffer);
	}

	STRUCT_SECTION_FOREACH(log_msg_ptr, msg_ptr) {
		struct log_mpsc_pbuf *buf;

		if (msg_ptr->msg) {
			return true;
		}

		STRUCT_SECTION_GET(log_mpsc_pbuf, i, &buf);

		if (msg_pending(&buf->buf)) {
			return true;
		}

		i++;
	}

	return false;
}

void z_log_msg_enqueue(const struct log_link *link, const void *data, size_t len)
{
	struct log_msg *log_msg = (struct log_msg *)data;
	size_t wlen = DIV_ROUND_UP(ROUND_UP(len, Z_LOG_MSG_ALIGNMENT), sizeof(int));
	struct mpsc_pbuf_buffer *mpsc_pbuffer = link->mpsc_pbuf ? link->mpsc_pbuf : &log_buffer;
	struct log_msg *local_msg = msg_alloc(mpsc_pbuffer, wlen);

	if (!local_msg) {
		z_log_dropped(false);
		return;
	}

	log_msg->hdr.desc.valid = 0;
	log_msg->hdr.desc.busy = 0;
	log_msg->hdr.desc.domain += link->ctrl_blk->domain_offset;
	memcpy((void *)local_msg, data, len);
	msg_commit(mpsc_pbuffer, local_msg);
}

const char *z_log_get_tag(void)
{
	return CONFIG_LOG_TAG_MAX_LEN > 0 ? tag : NULL;
}

int log_set_tag(const char *str)
{
#if CONFIG_LOG_TAG_MAX_LEN > 0
	if (str == NULL) {
		return -EINVAL;
	}

	size_t len = strlen(str);
	size_t cpy_len = MIN(len, CONFIG_LOG_TAG_MAX_LEN);

	memcpy(tag, str, cpy_len);
	tag[cpy_len] = '\0';

	if (cpy_len < len) {
		tag[cpy_len - 1] = '~';
		return -ENOMEM;
	}

	return 0;
#else
	return -ENOTSUP;
#endif
}

int log_mem_get_usage(uint32_t *buf_size, uint32_t *usage)
{
	__ASSERT_NO_MSG(buf_size != NULL);
	__ASSERT_NO_MSG(usage != NULL);

	if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
		return -EINVAL;
	}

	mpsc_pbuf_get_utilization(&log_buffer, buf_size, usage);

	return 0;
}

int log_mem_get_max_usage(uint32_t *max)
{
	__ASSERT_NO_MSG(max != NULL);

	if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
		return -EINVAL;
	}

	return mpsc_pbuf_get_max_utilization(&log_buffer, max);
}

static void log_backend_notify_all(enum log_backend_evt event,
				   union log_backend_evt_arg *arg)
{
	STRUCT_SECTION_FOREACH(log_backend, backend) {
		log_backend_notify(backend, event, arg);
	}
}

static void log_process_thread_timer_expiry_fn(struct k_timer *timer)
{
	k_sem_give(&log_process_thread_sem);
}

static void log_process_thread_func(void *dummy1, void *dummy2, void *dummy3)
{
	__ASSERT_NO_MSG(log_backend_count_get() > 0);
	uint32_t links_active_mask = 0xFFFFFFFF;
	uint8_t domain_offset = 0;
	uint32_t activate_mask = z_log_init(false, false);
	/* If some backends are not activated yet set periodical thread wake up
	 * to poll backends for readiness. Period is set arbitrary.
	 * If all backends are ready periodic wake up is not needed.
	 */
	k_timeout_t timeout = (activate_mask != 0) ? K_MSEC(50) : K_FOREVER;
	bool processed_any = false;
	thread_set(k_current_get());

	/* Logging thread is periodically waken up until all backends that
	 * should be autostarted are ready.
	 */
	while (true) {
		if (activate_mask) {
			activate_mask = activate_foreach_backend(activate_mask);
			if (!activate_mask) {
				/* Periodic wake up no longer needed since all
				 * backends are ready.
				 */
				timeout = K_FOREVER;
			}
		}

		/* Keep trying to activate links until all links are active. */
		if (IS_ENABLED(CONFIG_LOG_MULTIDOMAIN) && links_active_mask) {
			links_active_mask =
				z_log_links_activate(links_active_mask, &domain_offset);
		}


		if (log_process() == false) {
			if (processed_any) {
				processed_any = false;
				log_backend_notify_all(LOG_BACKEND_EVT_PROCESS_THREAD_DONE, NULL);
			}
			(void)k_sem_take(&log_process_thread_sem, timeout);
		} else {
			processed_any = true;
		}
	}
}

K_KERNEL_STACK_DEFINE(logging_stack, CONFIG_LOG_PROCESS_THREAD_STACK_SIZE);
struct k_thread logging_thread;

static int enable_logger(void)
{
	if (IS_ENABLED(CONFIG_LOG_PROCESS_THREAD)) {
		k_timer_init(&log_process_thread_timer,
				log_process_thread_timer_expiry_fn, NULL);
		/* start logging thread */
		k_thread_create(&logging_thread, logging_stack,
				K_KERNEL_STACK_SIZEOF(logging_stack),
				log_process_thread_func, NULL, NULL, NULL,
				LOG_PROCESS_THREAD_PRIORITY, 0,
				COND_CODE_1(CONFIG_LOG_PROCESS_THREAD,
					K_MSEC(CONFIG_LOG_PROCESS_THREAD_STARTUP_DELAY_MS),
					K_NO_WAIT));
		k_thread_name_set(&logging_thread, "logging");
	} else {
		(void)z_log_init(false, false);
	}

	return 0;
}

SYS_INIT(enable_logger, POST_KERNEL, CONFIG_LOG_CORE_INIT_PRIORITY);
