/*-------------------------------------------------------------------------
 * Logging framework for frontend programs
 *
 * Copyright (c) 2018-2021, PostgreSQL Global Development Group
 *
 * src/common/logging.c
 *
 *-------------------------------------------------------------------------
 */

#ifndef FRONTEND
#error "This file is not expected to be compiled for backend code"
#endif

#include "postgres_fe.h"

#include <unistd.h>

#include "common/logging.h"

enum pg_log_level __pg_log_level;

static const char *progname;
static int	log_flags;

static void (*log_pre_callback) (void);
static void (*log_locus_callback) (const char **, uint64 *);

static const char *sgr_error = NULL;
static const char *sgr_warning = NULL;
static const char *sgr_locus = NULL;

#define SGR_ERROR_DEFAULT "01;31"
#define SGR_WARNING_DEFAULT "01;35"
#define SGR_LOCUS_DEFAULT "01"

#define ANSI_ESCAPE_FMT "\x1b[%sm"
#define ANSI_ESCAPE_RESET "\x1b[0m"

#ifdef WIN32

#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif

/*
 * Attempt to enable VT100 sequence processing for colorization on Windows.
 * If current environment is not VT100-compatible or if this mode could not
 * be enabled, return false.
 */
static bool
enable_vt_processing(void)
{
	/* Check stderr */
	HANDLE		hOut = GetStdHandle(STD_ERROR_HANDLE);
	DWORD		dwMode = 0;

	if (hOut == INVALID_HANDLE_VALUE)
		return false;

	/*
	 * Look for the current console settings and check if VT100 is already
	 * enabled.
	 */
	if (!GetConsoleMode(hOut, &dwMode))
		return false;
	if ((dwMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0)
		return true;

	dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
	if (!SetConsoleMode(hOut, dwMode))
		return false;
	return true;
}
#endif							/* WIN32 */

/*
 * This should be called before any output happens.
 */
void
pg_logging_init(const char *argv0)
{
	const char *pg_color_env = getenv("PG_COLOR");
	bool		log_color = false;
	bool		color_terminal = isatty(fileno(stderr));

#ifdef WIN32

	/*
	 * On Windows, check if environment is VT100-compatible if using a
	 * terminal.
	 */
	if (color_terminal)
		color_terminal = enable_vt_processing();
#endif

	/* usually the default, but not on Windows */
	setvbuf(stderr, NULL, _IONBF, 0);

	progname = get_progname(argv0);
	__pg_log_level = PG_LOG_INFO;

	if (pg_color_env)
	{
		if (strcmp(pg_color_env, "always") == 0 ||
			(strcmp(pg_color_env, "auto") == 0 && color_terminal))
			log_color = true;
	}

	if (log_color)
	{
		const char *pg_colors_env = getenv("PG_COLORS");

		if (pg_colors_env)
		{
			char	   *colors = strdup(pg_colors_env);

			if (colors)
			{
				for (char *token = strtok(colors, ":"); token; token = strtok(NULL, ":"))
				{
					char	   *e = strchr(token, '=');

					if (e)
					{
						char	   *name;
						char	   *value;

						*e = '\0';
						name = token;
						value = e + 1;

						if (strcmp(name, "error") == 0)
							sgr_error = strdup(value);
						if (strcmp(name, "warning") == 0)
							sgr_warning = strdup(value);
						if (strcmp(name, "locus") == 0)
							sgr_locus = strdup(value);
					}
				}

				free(colors);
			}
		}
		else
		{
			sgr_error = SGR_ERROR_DEFAULT;
			sgr_warning = SGR_WARNING_DEFAULT;
			sgr_locus = SGR_LOCUS_DEFAULT;
		}
	}
}

void
pg_logging_config(int new_flags)
{
	log_flags = new_flags;
}

/*
 * pg_logging_init sets the default log level to INFO.  Programs that prefer
 * a different default should use this to set it, immediately afterward.
 */
void
pg_logging_set_level(enum pg_log_level new_level)
{
	__pg_log_level = new_level;
}

/*
 * Command line switches such as --verbose should invoke this.
 */
void
pg_logging_increase_verbosity(void)
{
	/*
	 * The enum values are chosen such that we have to decrease __pg_log_level
	 * in order to become more verbose.
	 */
	if (__pg_log_level > PG_LOG_NOTSET + 1)
		__pg_log_level--;
}

void
pg_logging_set_pre_callback(void (*cb) (void))
{
	log_pre_callback = cb;
}

void
pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno))
{
	log_locus_callback = cb;
}

void
pg_log_generic(enum pg_log_level level, const char *pg_restrict fmt,...)
{
	va_list		ap;

	va_start(ap, fmt);
	pg_log_generic_v(level, fmt, ap);
	va_end(ap);
}

void
pg_log_generic_v(enum pg_log_level level, const char *pg_restrict fmt, va_list ap)
{
	int			save_errno = errno;
	const char *filename = NULL;
	uint64		lineno = 0;
	va_list		ap2;
	size_t		required_len;
	char	   *buf;

	Assert(progname);
	Assert(level);
	Assert(fmt);
	Assert(fmt[strlen(fmt) - 1] != '\n');

	/*
	 * Flush stdout before output to stderr, to ensure sync even when stdout
	 * is buffered.
	 */
	fflush(stdout);

	if (log_pre_callback)
		log_pre_callback();

	if (log_locus_callback)
		log_locus_callback(&filename, &lineno);

	fmt = _(fmt);

	if (!(log_flags & PG_LOG_FLAG_TERSE) || filename)
	{
		if (sgr_locus)
			fprintf(stderr, ANSI_ESCAPE_FMT, sgr_locus);
		if (!(log_flags & PG_LOG_FLAG_TERSE))
			fprintf(stderr, "%s:", progname);
		if (filename)
		{
			fprintf(stderr, "%s:", filename);
			if (lineno > 0)
				fprintf(stderr, UINT64_FORMAT ":", lineno);
		}
		fprintf(stderr, " ");
		if (sgr_locus)
			fprintf(stderr, ANSI_ESCAPE_RESET);
	}

	if (!(log_flags & PG_LOG_FLAG_TERSE))
	{
		switch (level)
		{
			case PG_LOG_FATAL:
				if (sgr_error)
					fprintf(stderr, ANSI_ESCAPE_FMT, sgr_error);
				fprintf(stderr, _("fatal: "));
				if (sgr_error)
					fprintf(stderr, ANSI_ESCAPE_RESET);
				break;
			case PG_LOG_ERROR:
				if (sgr_error)
					fprintf(stderr, ANSI_ESCAPE_FMT, sgr_error);
				fprintf(stderr, _("error: "));
				if (sgr_error)
					fprintf(stderr, ANSI_ESCAPE_RESET);
				break;
			case PG_LOG_WARNING:
				if (sgr_warning)
					fprintf(stderr, ANSI_ESCAPE_FMT, sgr_warning);
				fprintf(stderr, _("warning: "));
				if (sgr_warning)
					fprintf(stderr, ANSI_ESCAPE_RESET);
				break;
			default:
				break;
		}
	}

	errno = save_errno;

	va_copy(ap2, ap);
	required_len = vsnprintf(NULL, 0, fmt, ap2) + 1;
	va_end(ap2);

	buf = pg_malloc_extended(required_len, MCXT_ALLOC_NO_OOM);

	errno = save_errno;			/* malloc might change errno */

	if (!buf)
	{
		/* memory trouble, just print what we can and get out of here */
		vfprintf(stderr, fmt, ap);
		return;
	}

	vsnprintf(buf, required_len, fmt, ap);

	/* strip one newline, for PQerrorMessage() */
	if (required_len >= 2 && buf[required_len - 2] == '\n')
		buf[required_len - 2] = '\0';

	fprintf(stderr, "%s\n", buf);

	free(buf);
}
