/*
 * Copyright (c) 2010, 2013-2014 Wind River Systems, Inc.
 * Copyright (c) 2020 Nordic Semiconductor ASA
 * Copyright (c) 2021 BayLibre, SAS
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <zephyr/sys/cbprintf.h>
#include <sys/types.h>
#include <zephyr/sys/util.h>

#ifdef CONFIG_CBPRINTF_FULL_INTEGRAL
typedef intmax_t int_value_type;
typedef uintmax_t uint_value_type;
#define DIGITS_BUFLEN 21
BUILD_ASSERT(sizeof(uint_value_type) <= 8U,
	     "DIGITS_BUFLEN may be incorrect");
#else
typedef int32_t int_value_type;
typedef uint32_t uint_value_type;
#define DIGITS_BUFLEN 10
#endif

#define ALPHA(fmt) (((fmt) & 0x60) - '0' - 10 + 1)

/* Convert value to string, storing characters downwards */
static inline int convert_value(uint_value_type num, unsigned int base,
				unsigned int alpha, char *buftop)
{
	int i = 0;

	do {
		unsigned int c = num % base;
		if (c >= 10) {
			c += alpha;
		}
		buftop[i--] = c + '0';
		num /= base;
	} while (num);

	return -i;
}

#define OUTC(_c) do { \
	out((int)(_c), ctx); \
	if (IS_ENABLED(CONFIG_CBPRINTF_LIBC_SUBSTS)) { \
		++count; \
	} \
} while (false)

#define PAD_ZERO	BIT(0)
#define PAD_TAIL	BIT(1)

/* Skip over the argument tag if needed as it is not being used here. */
#define SKIP_TAG_IF_NEEDED(ap, tagged_ap) \
	do { \
		if (IS_ENABLED(CONFIG_CBPRINTF_PACKAGE_SUPPORT_TAGGED_ARGUMENTS) \
		    && tagged_ap) { \
			(void)va_arg(ap, int); \
		} \
	} while (0)

/**
 * @brief Printk internals
 *
 * See printk() for description.
 * @param fmt Format string
 * @param ap Variable parameters
 *
 * @return printed byte count if CONFIG_CBPRINTF_LIBC_SUBSTS is set
 */
int z_cbvprintf_impl(cbprintf_cb __out, void *ctx, const char *fmt,
		     va_list ap, uint32_t flags)
{
	size_t count = 0;
	char buf[DIGITS_BUFLEN];
	char *prefix, *data;
	int min_width, precision, data_len;
	char padding_mode, length_mod, special;
	cbprintf_cb_local out = __out;

	const bool tagged_ap = (flags & Z_CBVPRINTF_PROCESS_FLAG_TAGGED_ARGS)
			       == Z_CBVPRINTF_PROCESS_FLAG_TAGGED_ARGS;

	/* we pre-increment in the loop  afterwards */
	fmt--;

start:
	while (*++fmt != '%') {
		if (*fmt == '\0') {
			return count;
		}
		OUTC(*fmt);
	}

	min_width = -1;
	precision = -1;
	prefix = "";
	padding_mode = 0;
	length_mod = 0;
	special = 0;

	for (fmt++ ; ; fmt++) {
		switch (*fmt) {
		case 0:
			return count;

		case '%':
			OUTC('%');
			goto start;

		case '-':
			padding_mode = PAD_TAIL;
			continue;

		case '.':
			precision = 0;
			padding_mode &= (char)~PAD_ZERO;
			continue;

		case '0':
			if (min_width < 0 && precision < 0 && !padding_mode) {
				padding_mode = PAD_ZERO;
				continue;
			}
			__fallthrough;

		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			if (precision >= 0) {
				precision = 10 * precision + *fmt - '0';
			} else {
				if (min_width < 0) {
					min_width = 0;
				}
				min_width = 10 * min_width + *fmt - '0';
			}
			continue;

		case '*':
			SKIP_TAG_IF_NEEDED(ap, tagged_ap);

			if (precision >= 0) {
				precision = va_arg(ap, int);
			} else {
				min_width = va_arg(ap, int);
				if (min_width < 0) {
					min_width = -min_width;
					padding_mode = PAD_TAIL;
				}
			}
			continue;

		case '+':
		case ' ':
		case '#':
			special = *fmt;
			continue;

		case 'h':
		case 'l':
		case 'z':
			if (*fmt == 'h' && length_mod == 'h') {
				length_mod = 'H';
			} else if (*fmt == 'l' && length_mod == 'l') {
				length_mod = 'L';
			} else if (length_mod == '\0') {
				length_mod = *fmt;
			} else {
				OUTC('%');
				OUTC(*fmt);
				goto start;
			}
			continue;

		case 'd':
		case 'i':
		case 'u': {
			uint_value_type d;

			SKIP_TAG_IF_NEEDED(ap, tagged_ap);

			if (length_mod == 'z') {
				if (*fmt == 'u') {
					d = va_arg(ap, size_t);
				} else {
					d = va_arg(ap, ssize_t);
				}
			} else if (length_mod == 'l') {
				if (*fmt == 'u') {
					d = va_arg(ap, unsigned long);
				} else {
					d = va_arg(ap, long);
				}
			} else if (length_mod == 'L') {
				if (*fmt == 'u') {
					unsigned long long llu =
						va_arg(ap, unsigned long long);

					if (llu != (uint_value_type) llu) {
						data = "ERR";
						data_len = 3;
						precision = 0;
						break;
					}
					d = (uint_value_type) llu;
				} else {
					long long lld = va_arg(ap, long long);

					if (lld != (int_value_type) lld) {
						data = "ERR";
						data_len = 3;
						precision = 0;
						break;
					}
					d = (int_value_type) lld;
				}
			} else if (*fmt == 'u') {
				d = va_arg(ap, unsigned int);
			} else {
				d = va_arg(ap, int);
			}

			if (*fmt != 'u' && (int_value_type)d < 0) {
				d = -d;
				prefix = "-";
				min_width--;
			} else if (special == ' ') {
				prefix = " ";
				min_width--;
			} else if (special == '+') {
				prefix = "+";
				min_width--;
			} else {
				;
			}
			data_len = convert_value(d, 10, 0, buf + sizeof(buf) - 1);
			data = buf + sizeof(buf) - data_len;
			break;
		}

		case 'p':
		case 'x':
		case 'X': {
			uint_value_type x;

			SKIP_TAG_IF_NEEDED(ap, tagged_ap);

			if (*fmt == 'p') {
				x = (uintptr_t)va_arg(ap, void *);
				if (x == (uint_value_type)0) {
					data = "(nil)";
					data_len = 5;
					precision = 0;
					break;
				}
				special = '#';
			} else if (length_mod == 'l') {
				x = va_arg(ap, unsigned long);
			} else if (length_mod == 'L') {
				unsigned long long llx =
					va_arg(ap, unsigned long long);

				if (llx != (uint_value_type) llx) {
					data = "ERR";
					data_len = 3;
					precision = 0;
					break;
				}
				x = (uint_value_type) llx;
			} else {
				x = va_arg(ap, unsigned int);
			}
			if (special == '#') {
				prefix = (*fmt & 0x20) ? "0x" : "0X";
				min_width -= 2;
			}
			data_len = convert_value(x, 16, ALPHA(*fmt),
						 buf + sizeof(buf) - 1);
			data = buf + sizeof(buf) - data_len;
			break;
		}

		case 's': {
			SKIP_TAG_IF_NEEDED(ap, tagged_ap);

			data = va_arg(ap, char *);
			data_len = strlen(data);
			if (precision >= 0 && data_len > precision) {
				data_len = precision;
			}
			precision = 0;
			break;
		}

		case 'c': {
			int c;

			SKIP_TAG_IF_NEEDED(ap, tagged_ap);

			c = va_arg(ap, int);

			buf[0] = c;
			data = buf;
			data_len = 1;
			precision = 0;
			break;
		}

		default:
			OUTC('%');
			OUTC(*fmt);
			goto start;
		}

		if (precision < 0 && (padding_mode & PAD_ZERO)) {
			precision = min_width;
		}
		min_width -= data_len;
		precision -= data_len;
		if (precision > 0) {
			min_width -= precision;
		}

		if (!(padding_mode & PAD_TAIL)) {
			while (--min_width >= 0) {
				OUTC(' ');
			}
		}
		while (*prefix) {
			OUTC(*prefix++);
		}
		while (--precision >= 0) {
			OUTC('0');
		}
		while (--data_len >= 0) {
			OUTC(*data++);
		}
		while (--min_width >= 0) {
			OUTC(' ');
		}

		goto start;
	}
}
