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

#include <logging/log_output.h>
#include <logging/log_ctrl.h>
#include <logging/log.h>
#include <assert.h>
#include <ctype.h>
#include <time.h>
#include <stdio.h>
#include <stdbool.h>

#define LOG_COLOR_CODE_DEFAULT "\x1B[0m"
#define LOG_COLOR_CODE_RED     "\x1B[1;31m"
#define LOG_COLOR_CODE_YELLOW  "\x1B[1;33m"

#define HEXDUMP_BYTES_IN_LINE 8

#define  DROPPED_COLOR_PREFIX \
	Z_LOG_EVAL(CONFIG_LOG_BACKEND_SHOW_COLOR, (LOG_COLOR_CODE_RED), ())

#define DROPPED_COLOR_POSTFIX \
	Z_LOG_EVAL(CONFIG_LOG_BACKEND_SHOW_COLOR, (LOG_COLOR_CODE_DEFAULT), ())

static const char *const severity[] = {
	NULL,
	"err",
	"wrn",
	"inf",
	"dbg"
};

static const char *const colors[] = {
	NULL,
	LOG_COLOR_CODE_RED,     /* err */
	LOG_COLOR_CODE_YELLOW,  /* warn */
	NULL,                   /* info */
	NULL                    /* dbg */
};

static u32_t freq;
static u32_t timestamp_div;

typedef int (*out_func_t)(int c, void *ctx);

extern int _prf(int (*func)(), void *dest, char *format, va_list vargs);
extern void _vprintk(out_func_t out, void *log_output,
		     const char *fmt, va_list ap);

/* The RFC 5424 allows very flexible mapping and suggest the value 0 being the
 * highest severity and 7 to be the lowest (debugging level) severity.
 *
 *    0   Emergency      System is unusable
 *    1   Alert          Action must be taken immediately
 *    2   Critical       Critical conditions
 *    3   Error          Error conditions
 *    4   Warning        Warning conditions
 *    5   Notice         Normal but significant condition
 *    6   Informational  Informational messages
 *    7   Debug          Debug-level messages
 */
static int level_to_rfc5424_severity(u32_t level)
{
	u8_t ret;

	switch (level) {
	case LOG_LEVEL_NONE:
		ret = 7;
		break;
	case LOG_LEVEL_ERR:
		ret =  3;
		break;
	case LOG_LEVEL_WRN:
		ret =  4;
		break;
	case LOG_LEVEL_INF:
		ret =  6;
		break;
	case LOG_LEVEL_DBG:
		ret = 7;
		break;
	default:
		ret = 7;
		break;
	}

	return ret;
}

static int out_func(int c, void *ctx)
{
	const struct log_output *out_ctx =
					(const struct log_output *)ctx;

	out_ctx->buf[out_ctx->control_block->offset] = (u8_t)c;
	out_ctx->control_block->offset++;

	__ASSERT_NO_MSG(out_ctx->control_block->offset <= out_ctx->size);

	if (out_ctx->control_block->offset == out_ctx->size) {
		log_output_flush(out_ctx);
	}

	return 0;
}

static int print_formatted(const struct log_output *log_output,
			   const char *fmt, ...)
{
	va_list args;
	int length = 0;

	va_start(args, fmt);
#if !defined(CONFIG_NEWLIB_LIBC) && !defined(CONFIG_ARCH_POSIX) && \
    defined(CONFIG_LOG_ENABLE_FANCY_OUTPUT_FORMATTING)
	length = _prf(out_func, (void *)log_output, (char *)fmt, args);
#else
	_vprintk(out_func, (void *)log_output, fmt, args);
#endif
	va_end(args);

	return length;
}

static void buffer_write(log_output_func_t outf, u8_t *buf, size_t len,
			 void *ctx)
{
	int processed;

	do {
		processed = outf(buf, len, ctx);
		len -= processed;
		buf += processed;
	} while (len != 0);
}

void log_output_flush(const struct log_output *log_output)
{
	buffer_write(log_output->func, log_output->buf,
		     log_output->control_block->offset,
		     log_output->control_block->ctx);

	log_output->control_block->offset = 0;
}

static int timestamp_print(const struct log_output *log_output,
			   u32_t flags, u32_t timestamp)
{
	int length;
	bool format =
		(flags & LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP) |
		(flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG);


	if (!format) {
		length = print_formatted(log_output, "[%08lu] ", timestamp);
	} else if (freq != 0) {
		u32_t remainder;
		u32_t seconds;
		u32_t hours;
		u32_t mins;
		u32_t ms;
		u32_t us;

		timestamp /= timestamp_div;
		seconds = timestamp / freq;
		hours = seconds / 3600;
		seconds -= hours * 3600;
		mins = seconds / 60;
		seconds -= mins * 60;

		remainder = timestamp % freq;
		ms = (remainder * 1000) / freq;
		us = (1000 * (1000 * remainder - (ms * freq))) / freq;

		if (IS_ENABLED(CONFIG_LOG_BACKEND_NET) &&
		    flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) {
#if defined(CONFIG_NEWLIB_LIBC)
			char time_str[sizeof("1970-01-01T00:00:00")];
			struct tm *tm;
			time_t time;

			time = seconds;
			tm = gmtime(&time);

			strftime(time_str, sizeof(time_str), "%FT%T", tm);

			length = print_formatted(log_output, "%s.%06dZ ",
						 time_str, ms * 1000 + us);
#else
			length = print_formatted(log_output,
					"1970-01-01T%02d:%02d:%02d.%06dZ ",
					hours, mins, seconds, ms * 1000 + us);
#endif
		} else {
			length = print_formatted(log_output,
						 "[%02d:%02d:%02d.%03d,%03d] ",
						 hours, mins, seconds, ms, us);
		}
	} else {
		length = 0;
	}

	return length;
}

static void color_print(const struct log_output *log_output,
			bool color, bool start, u32_t level)
{
	if (color) {
		const char *color = start && (colors[level] != NULL) ?
				colors[level] : LOG_COLOR_CODE_DEFAULT;
		print_formatted(log_output, "%s", color);
	}
}

static void color_prefix(const struct log_output *log_output,
			 bool color, u32_t level)
{
	color_print(log_output, color, true, level);
}

static void color_postfix(const struct log_output *log_output,
			  bool color, u32_t level)
{
	color_print(log_output, color, false, level);
}


static int ids_print(const struct log_output *log_output, bool level_on,
		    bool func_on, u32_t domain_id, u32_t source_id, u32_t level)
{
	int total = 0;

	if (level_on) {
		total += print_formatted(log_output, "<%s> ", severity[level]);
	}

	total += print_formatted(log_output,
				(func_on &&
				((1 << level) & LOG_FUNCTION_PREFIX_MASK)) ?
				"%s." : "%s: ",
				log_source_name_get(domain_id, source_id));

	return total;
}

static void newline_print(const struct log_output *ctx, u32_t flags)
{
	if (IS_ENABLED(CONFIG_LOG_BACKEND_NET) &&
	    flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) {
		return;
	}

	if ((flags & LOG_OUTPUT_FLAG_CRLF_NONE) != 0) {
		return;
	}

	if ((flags & LOG_OUTPUT_FLAG_CRLF_LFONLY) != 0) {
		print_formatted(ctx, "\n");
	} else {
		print_formatted(ctx, "\r\n");
	}
}

static void std_print(struct log_msg *msg,
		      const struct log_output *log_output)
{
	const char *str = log_msg_str_get(msg);
	u32_t nargs = log_msg_nargs_get(msg);
	u32_t *args = alloca(sizeof(u32_t)*nargs);
	int i;

	for (i = 0; i < nargs; i++) {
		args[i] = log_msg_arg_get(msg, i);
	}

	switch (log_msg_nargs_get(msg)) {
	case 0:
		print_formatted(log_output, str);
		break;
	case 1:
		print_formatted(log_output, str, args[0]);
		break;
	case 2:
		print_formatted(log_output, str, args[0], args[1]);
		break;
	case 3:
		print_formatted(log_output, str, args[0], args[1], args[2]);
		break;
	case 4:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3]);
		break;
	case 5:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4]);
		break;
	case 6:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5]);
		break;
	case 7:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5], args[6]);
		break;
	case 8:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5], args[6], args[7]);
		break;
	case 9:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5], args[6],  args[7],
				args[8]);
		break;
	case 10:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5], args[6],  args[7],
				args[8], args[9]);
		break;
	case 11:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5], args[6],  args[7],
				args[8], args[9], args[10]);
		break;
	case 12:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5], args[6],  args[7],
				args[8], args[9], args[10], args[11]);
		break;
	case 13:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5], args[6],  args[7],
				args[8], args[9], args[10], args[11], args[12]);
		break;
	case 14:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5], args[6],  args[7],
				args[8], args[9], args[10], args[11], args[12],
				args[13]);
		break;
	case 15:
		print_formatted(log_output, str, args[0], args[1], args[2],
				args[3], args[4], args[5], args[6],  args[7],
				args[8], args[9], args[10], args[11], args[12],
				args[13], args[14]);
		break;
	default:
		/* Unsupported number of arguments. */
		__ASSERT_NO_MSG(true);
		break;
	}
}

static void hexdump_line_print(const struct log_output *log_output,
			       const u8_t *data, u32_t length,
			       int prefix_offset, u32_t flags)
{
	newline_print(log_output, flags);

	for (int i = 0; i < prefix_offset; i++) {
		print_formatted(log_output, " ");
	}

	for (int i = 0; i < HEXDUMP_BYTES_IN_LINE; i++) {
		if (i < length) {
			print_formatted(log_output, "%02x ", data[i]);
		} else {
			print_formatted(log_output, "   ");
		}
	}

	print_formatted(log_output, "|");

	for (int i = 0; i < HEXDUMP_BYTES_IN_LINE; i++) {
		if (i < length) {
			char c = (char)data[i];

			print_formatted(log_output, "%c",
			      isprint((int)c) ? c : '.');
		} else {
			print_formatted(log_output, " ");
		}
	}
}

static void hexdump_print(struct log_msg *msg,
			  const struct log_output *log_output,
			  int prefix_offset, u32_t flags)
{
	u32_t offset = 0U;
	u8_t buf[HEXDUMP_BYTES_IN_LINE];
	size_t length;

	print_formatted(log_output, "%s", log_msg_str_get(msg));

	do {
		length = sizeof(buf);
		log_msg_hexdump_data_get(msg, buf, &length, offset);

		if (length) {
			hexdump_line_print(log_output, buf, length,
					   prefix_offset, flags);
			offset += length;
		} else {
			break;
		}
	} while (true);
}

static void raw_string_print(struct log_msg *msg,
			     const struct log_output *log_output)
{
	__ASSERT_NO_MSG(log_output->size);

	size_t offset = 0;
	size_t length;
	bool eol = false;

	do {
		length = log_output->size;
		/* Sting is stored in a hexdump message. */
		log_msg_hexdump_data_get(msg, log_output->buf, &length, offset);
		log_output->control_block->offset = length;

		if (length != 0) {
			eol = (log_output->buf[length - 1] == '\n');
		}

		log_output_flush(log_output);
		offset += length;
	} while (length > 0);

	if (eol) {
		print_formatted(log_output, "\r");
	}
}

static u32_t prefix_print(const struct log_output *log_output,
			 u32_t flags, bool func_on, u32_t timestamp, u8_t level,
			 u8_t domain_id, u16_t source_id)
{
	u32_t length = 0;

	bool stamp = flags & LOG_OUTPUT_FLAG_TIMESTAMP;
	bool colors_on = flags & LOG_OUTPUT_FLAG_COLORS;
	bool level_on = flags & LOG_OUTPUT_FLAG_LEVEL;

	if (IS_ENABLED(CONFIG_LOG_BACKEND_NET) &&
	    flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) {
		/* TODO: As there is no way to figure out the
		 * facility at this point, use a pre-defined value.
		 * Change this to use the real facility of the
		 * logging call when that info is available.
		 */
		static const int facility = 16; /* local0 */

		length += print_formatted(
			log_output,
			"<%d>1 ",
			facility * 8 +
			level_to_rfc5424_severity(level));
	}

	if (stamp) {
		length += timestamp_print(log_output, flags, timestamp);
	}

	if (IS_ENABLED(CONFIG_LOG_BACKEND_NET) &&
	    flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) {
		length += print_formatted(
			log_output, "%s - - - - ",
			log_output->control_block->hostname ?
			log_output->control_block->hostname :
			"zephyr");

	} else {
		color_prefix(log_output, colors_on, level);
		length += ids_print(log_output, level_on, func_on,
				    domain_id, source_id, level);
	}

	return length;
}

static void postfix_print(const struct log_output *log_output,
			  u32_t flags, u8_t level)
{
	color_postfix(log_output, (flags & LOG_OUTPUT_FLAG_COLORS),
			      level);
	newline_print(log_output, flags);
}

void log_output_msg_process(const struct log_output *log_output,
			    struct log_msg *msg,
			    u32_t flags)
{
	bool std_msg = log_msg_is_std(msg);
	u32_t timestamp = log_msg_timestamp_get(msg);
	u8_t level = (u8_t)log_msg_level_get(msg);
	u8_t domain_id = (u8_t)log_msg_domain_id_get(msg);
	u16_t source_id = (u16_t)log_msg_source_id_get(msg);
	bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING);
	int prefix_offset;

	prefix_offset = raw_string ?
			0 : prefix_print(log_output, flags, std_msg, timestamp,
					 level, domain_id, source_id);

	if (log_msg_is_std(msg)) {
		std_print(msg, log_output);
	} else if (raw_string) {
		raw_string_print(msg, log_output);
	} else {
		hexdump_print(msg, log_output, prefix_offset, flags);
	}

	if (!raw_string) {
		postfix_print(log_output, flags, level);
	}

	log_output_flush(log_output);
}

static bool ends_with_newline(const char *fmt)
{
	char c = '\0';

	while (*fmt != '\0') {
		c = *fmt;
		fmt++;
	}

	return (c == '\n');
}

void log_output_string(const struct log_output *log_output,
		       struct log_msg_ids src_level, u32_t timestamp,
		       const char *fmt, va_list ap, u32_t flags)
{
	int length;
	u8_t level = (u8_t)src_level.level;
	u8_t domain_id = (u8_t)src_level.domain_id;
	u16_t source_id = (u16_t)src_level.source_id;
	bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING);

	if (!raw_string) {
		prefix_print(log_output, flags, true, timestamp,
				level, domain_id, source_id);
	}

#if !defined(CONFIG_NEWLIB_LIBC) && !defined(CONFIG_ARCH_POSIX) && \
    defined(CONFIG_LOG_ENABLE_FANCY_OUTPUT_FORMATTING)
	length = _prf(out_func, (void *)log_output, (char *)fmt, ap);
#else
	_vprintk(out_func, (void *)log_output, fmt, ap);
#endif

	(void)length;

	if (raw_string) {
		/* add \r if string ends with newline. */
		if (ends_with_newline(fmt)) {
			print_formatted(log_output, "\r");
		}
	} else {
		postfix_print(log_output, flags, level);
	}

	log_output_flush(log_output);
}

void log_output_hexdump(const struct log_output *log_output,
			     struct log_msg_ids src_level, u32_t timestamp,
			     const char *metadata, const u8_t *data,
			     u32_t length, u32_t flags)
{
	u32_t prefix_offset;
	u8_t level = (u8_t)src_level.level;
	u8_t domain_id = (u8_t)src_level.domain_id;
	u16_t source_id = (u16_t)src_level.source_id;

	prefix_offset = prefix_print(log_output, flags, true, timestamp,
				     level, domain_id, source_id);

	/* Print metadata */
	print_formatted(log_output, "%s", metadata);

	while (length) {
		u32_t part_len = length > HEXDUMP_BYTES_IN_LINE ?
				HEXDUMP_BYTES_IN_LINE : length;

		hexdump_line_print(log_output, data, part_len,
				   prefix_offset, flags);

		data += part_len;
		length -= part_len;
	};

	postfix_print(log_output, flags, level);
	log_output_flush(log_output);
}

void log_output_dropped_process(const struct log_output *log_output, u32_t cnt)
{
	char buf[5];
	int len;
	static const char prefix[] = DROPPED_COLOR_PREFIX "--- ";
	static const char postfix[] =
			" messages dropped ---\r\n" DROPPED_COLOR_POSTFIX;
	log_output_func_t outf = log_output->func;
	struct device *dev = (struct device *)log_output->control_block->ctx;

	cnt = MIN(cnt, 9999);
	len = snprintf(buf, sizeof(buf), "%d", cnt);

	buffer_write(outf, (u8_t *)prefix, sizeof(prefix) - 1, dev);
	buffer_write(outf, buf, len, dev);
	buffer_write(outf, (u8_t *)postfix, sizeof(postfix) - 1, dev);
}

void log_output_timestamp_freq_set(u32_t frequency)
{
	timestamp_div = 1U;
	/* There is no point to have frequency higher than 1MHz (ns are not
	 * printed) and too high frequency leads to overflows in calculations.
	 */
	while (frequency > 1000000) {
		frequency /= 2;
		timestamp_div *= 2;
	}

	freq = frequency;
}
