#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>

#include <haproxy/api.h>
#include <haproxy/applet-t.h>
#include <haproxy/buf.h>
#include <haproxy/cli.h>
#include <haproxy/errors.h>
#include <haproxy/global.h>
#include <haproxy/obj_type.h>
#include <haproxy/ring.h>
#include <haproxy/tools.h>
#include <haproxy/version.h>

/* A global buffer used to store all startup alerts/warnings. It will then be
 * retrieve on the CLI. */
struct ring *startup_logs = NULL;
#ifdef USE_SHM_OPEN
static struct ring *shm_startup_logs = NULL;
#endif

/* A thread local buffer used to store all alerts/warnings. It can be used to
 * retrieve them for CLI commands after startup.
 */
#define USER_MESSAGES_BUFSIZE 1024
static THREAD_LOCAL struct buffer usermsgs_buf = BUF_NULL;

/* A thread local context used for stderr output via ha_alert/warning/notice/diag.
 */
#define USERMSGS_CTX_BUFSIZE   PATH_MAX
static THREAD_LOCAL struct usermsgs_ctx usermsgs_ctx = { .str = BUF_NULL, };

#ifdef USE_SHM_OPEN

/* initialise an SHM for the startup logs and return its fd */
static int startup_logs_new_shm()
{
	char *path = NULL;
	int fd = -1;
	int flags;

	/* create a unique path per PID so we don't collide with another
	   process */
	memprintf(&path, "/haproxy_startup_logs_%d", getpid());
	fd = shm_open(path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
	if (fd == -1)
		goto error;
	shm_unlink(path);
	ha_free(&path);

	if (ftruncate(fd, STARTUP_LOG_SIZE) == -1)
		goto error;

	flags = fcntl(fd, F_GETFD);
	if (flags == -1)
		goto error;
	flags &= ~FD_CLOEXEC;
	flags = fcntl(fd, F_SETFD, flags);
	if (flags == -1)
		goto error;

	return fd;
error:
	if (fd != -1) {
		close(fd);
		fd = -1;
	}
	return fd;
}

/* mmap a startup-logs from a <fd>.
 * if <new> is set to one, initialize the buffer.
 * Returns the ring.
 */
static struct ring *startup_logs_from_fd(int fd, int new)
{
	char *area;
	struct ring *r = NULL;

	if (fd == -1)
		goto error;

	area = mmap(NULL, STARTUP_LOG_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if (area == MAP_FAILED || area == NULL)
		goto error;

	if (new)
		r = ring_make_from_area(area, STARTUP_LOG_SIZE);
	else
		r = ring_cast_from_area(area);

	if (r == NULL)
		goto error;

	shm_startup_logs = r; /* save the ptr so we can unmap later */

	return r;
error:
	return NULL;
}

/*
 * Use a shm across reexec of the master.
 *
 * During the startup of the master, a shm_open must be done and the FD saved
 * into the HAPROXY_STARTUPLOGS_FD environment variable.
 *
 * When forking workers, the child must use a copy of the shm, not the shm itself.
 *
 * Once in wait mode, the shm must be copied and closed.
 *
 */
void startup_logs_init()
{
	struct ring *r = NULL;
	char *str_fd, *endptr;
	int fd = -1;

	str_fd = getenv("HAPROXY_STARTUPLOGS_FD");
	if (str_fd) {
		fd = strtol(str_fd, &endptr, 10);
		if (*endptr != '\0')
			goto error;
		unsetenv("HAPROXY_STARTUPLOGS_FD");
	}

	/* during startup, or just after a reload.
	 * Note: the WAIT_ONLY env variable must be
	 * check in case of an early call  */
	if (!(global.mode & MODE_MWORKER_WAIT) &&
	    getenv("HAPROXY_MWORKER_WAIT_ONLY") == NULL) {
		if (fd != -1)
			close(fd);

		fd = startup_logs_new_shm();
		if (fd == -1)
			goto error;

		r = startup_logs_from_fd(fd, 1);
		if (!r)
			goto error;

		str_fd = NULL;
		memprintf(&str_fd, "%d", fd);
		setenv("HAPROXY_STARTUPLOGS_FD", str_fd, 1);
		ha_free(&str_fd);

	} else {
		/* in wait mode, copy the shm to an allocated buffer */
		struct ring *prev = NULL;

		if (fd == -1)
			goto error;

		prev = startup_logs_from_fd(fd, 0);
		if (!prev)
			goto error;

		r = startup_logs_dup(prev);
		if (!r)
			goto error;
		startup_logs_free(prev);
		close(fd);
	}

	startup_logs = r;

	return;
error:
	if (fd != -1)
		close(fd);
	/* couldn't get a mmap to work */
	startup_logs = ring_new(STARTUP_LOG_SIZE);

}

#else /* ! USE_SHM_OPEN */

void startup_logs_init()
{
	startup_logs = ring_new(STARTUP_LOG_SIZE);
}

#endif

/* free the startup logs, unmap if it was an shm */
void startup_logs_free(struct ring *r)
{
#ifdef USE_SHM_OPEN
	if (r == shm_startup_logs)
		munmap(r, STARTUP_LOG_SIZE);
	else
#endif /* ! USE_SHM_OPEN */
		ring_free(r);
}

/* duplicate a startup logs which was previously allocated in a shm */
struct ring *startup_logs_dup(struct ring *src)
{
	struct ring *dst = NULL;

	/* must use the size of the previous buffer */
	dst = ring_new(b_size(&src->buf));
	if (!dst)
		goto error;

	b_reset(&dst->buf);
	b_ncat(&dst->buf, &src->buf, b_data(&src->buf));
error:
	return dst;
}

/* Put msg in usermsgs_buf.
 *
 * The message should not be terminated by a newline because this function
 * manually insert it.
 *
 * If there is not enough room in the buffer, the message is silently discarded.
 * Do not forget to frequently clear the buffer.
 */
static void usermsgs_put(const struct ist *msg)
{
	/* Allocate the buffer if not already done. */
	if (unlikely(b_is_null(&usermsgs_buf))) {
		usermsgs_buf.area = malloc(USER_MESSAGES_BUFSIZE * sizeof(char));
		usermsgs_buf.size = USER_MESSAGES_BUFSIZE;
	}

	if (likely(!b_is_null(&usermsgs_buf))) {
		if (b_room(&usermsgs_buf) >= msg->len + 2) {
			/* Insert the message + newline. */
			b_putblk(&usermsgs_buf, msg->ptr, msg->len);
			b_putchr(&usermsgs_buf, '\n');
			/* Insert NUL outside of the buffer. */
			*b_tail(&usermsgs_buf) = '\0';
		}
	}
}

/* Clear the user messages log buffer.
 *
 * <prefix> will set the local-thread context appended to every output
 * following this call. It can be NULL if not necessary.
 */
void usermsgs_clr(const char *prefix)
{
	if (likely(!b_is_null(&usermsgs_buf))) {
		b_reset(&usermsgs_buf);
		usermsgs_buf.area[0] = '\0';
	}

	usermsgs_ctx.prefix = prefix;
}

/* Check if the user messages buffer is empty. */
int usermsgs_empty(void)
{
	return !!(b_is_null(&usermsgs_buf) || !b_data(&usermsgs_buf));
}

/* Return the messages log buffer content. */
const char *usermsgs_str(void)
{
	if (unlikely(b_is_null(&usermsgs_buf)))
		return "";

	return b_head(&usermsgs_buf);
}

/* Set thread-local context infos to prefix forthcoming stderr output during
 * configuration parsing.
 *
 * <file> and <line> specify the location of the parsed configuration.
 *
 * <obj> can be of various types. If not NULL, the string prefix generated will
 * depend on its type.
 */
void set_usermsgs_ctx(const char *file, int line, enum obj_type *obj)
{
	usermsgs_ctx.file = file;
	usermsgs_ctx.line = line;
	usermsgs_ctx.obj = obj;
}

/* Set thread-local context infos to prefix forthcoming stderr output. It will
 * be set as a complement to possibly already defined file/line.
 *
 * <obj> can be of various types. If not NULL, the string prefix generated will
 * depend on its type.
 */
void register_parsing_obj(enum obj_type *obj)
{
	usermsgs_ctx.obj = obj;
}

/* Reset thread-local context infos for stderr output. */
void reset_usermsgs_ctx(void)
{
	usermsgs_ctx.file = NULL;
	usermsgs_ctx.line = 0;
	usermsgs_ctx.obj = NULL;
}

static void generate_usermsgs_ctx_str(void)
{
	struct usermsgs_ctx *ctx = &usermsgs_ctx;
	void *area;
	int ret;

	if (unlikely(b_is_null(&ctx->str))) {
		area = calloc(USERMSGS_CTX_BUFSIZE, sizeof(*area));
		if (area)
			ctx->str = b_make(area, USERMSGS_CTX_BUFSIZE, 0, 0);
	}

	if (likely(!b_is_null(&ctx->str))) {
		b_reset(&ctx->str);

		if (ctx->prefix) {
			ret = snprintf(b_tail(&ctx->str), b_room(&ctx->str),
			               "%s : ", ctx->prefix);
			b_add(&ctx->str, MIN(ret, b_room(&ctx->str)));
		}

		if (ctx->file) {
			ret = snprintf(b_tail(&ctx->str), b_room(&ctx->str),
			               "[%s:%d] : ", ctx->file, ctx->line);
			b_add(&ctx->str, MIN(ret, b_room(&ctx->str)));
		}

		switch (obj_type(ctx->obj)) {
		case OBJ_TYPE_SERVER:
			ret = snprintf(b_tail(&ctx->str), b_room(&ctx->str),
			               "'server %s/%s' : ",
			               __objt_server(ctx->obj)->proxy->id,
			               __objt_server(ctx->obj)->id);
			b_add(&ctx->str, MIN(ret, b_room(&ctx->str)));
			break;

		case OBJ_TYPE_NONE:
		default:
			break;
		}

		if (!b_data(&ctx->str))
			snprintf(b_tail(&ctx->str), b_room(&ctx->str), "%s", "");
	}
}

/* Generic function to display messages prefixed by a label */
static void print_message(int use_usermsgs_ctx, const char *label, const char *fmt, va_list argp)
{
	struct ist msg_ist = IST_NULL;
	char *head, *parsing_str, *msg;
	char prefix[11]; // '[' + 8 chars + ']' + 0.

	*prefix = '[';
	strncpy(prefix + 1, label, sizeof(prefix) - 2);
	msg = prefix + strlen(prefix);
	*msg++ = ']';
	while (msg < prefix + sizeof(prefix) - 1)
		*msg++ = ' ';
	*msg = 0;

	head = parsing_str = msg = NULL;
	memprintf(&head, "%s (%u) : ", prefix, (uint)getpid());
	memvprintf(&msg, fmt, argp);

	/* trim the trailing '\n' */
	msg_ist = ist(msg);
	if (msg_ist.len > 0 && msg_ist.ptr[msg_ist.len - 1] == '\n')
		msg_ist.len--;

	if (use_usermsgs_ctx) {
		generate_usermsgs_ctx_str();
		parsing_str = b_head(&usermsgs_ctx.str);
		reset_usermsgs_ctx();
	}
	else {
		parsing_str = "";
	}

	if (global.mode & MODE_STARTING) {
		if (unlikely(!startup_logs))
			startup_logs_init();

		if (likely(startup_logs)) {
			struct ist m[3];

			m[0] = ist(head);
			m[1] = ist(parsing_str);
			m[2] = msg_ist;

			ring_write(startup_logs, ~0, 0, 0, m, 3);
		}
	}
	else {
		usermsgs_put(&msg_ist);
	}

	fprintf(stderr, "%s%s%s", head, parsing_str, msg);
	fflush(stderr);

	free(head);
	free(msg);
}

static void print_message_args(int use_usermsgs_ctx, const char *label, const char *fmt, ...)
{
	va_list argp;
	va_start(argp, fmt);
	print_message(use_usermsgs_ctx, label, fmt, argp);
	va_end(argp);
}

/*
 * Displays the message on stderr with the pid. Overrides the quiet
 * mode during startup.
 */
void ha_alert(const char *fmt, ...)
{
	va_list argp;

	if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE) ||
	    !(global.mode & MODE_STARTING)) {
		if (!(warned & WARN_EXEC_PATH) && (global.mode & MODE_STARTING)) {
			const char *path = get_exec_path();

			warned |= WARN_EXEC_PATH;
			print_message_args(0, "NOTICE", "haproxy version is %s\n", haproxy_version);
			if (path)
				print_message_args(0, "NOTICE", "path to executable is %s\n", path);
		}
		va_start(argp, fmt);
		print_message(1, "ALERT", fmt, argp);
		va_end(argp);
	}
}

/*
 * Displays the message on stderr with the pid.
 */
void ha_warning(const char *fmt, ...)
{
	va_list argp;

	warned |= WARN_ANY;

	if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE) ||
	    !(global.mode & MODE_STARTING)) {
		if (!(warned & WARN_EXEC_PATH) && (global.mode & MODE_STARTING)) {
			const char *path = get_exec_path();

			warned |= WARN_EXEC_PATH;
			print_message_args(0, "NOTICE", "haproxy version is %s\n", haproxy_version);
			if (path)
				print_message_args(0, "NOTICE", "path to executable is %s\n", path);
		}
		va_start(argp, fmt);
		print_message(1, "WARNING", fmt, argp);
		va_end(argp);
	}
}

/*
 * Variant of _ha_diag_warning with va_list.
 * Use it only if MODE_DIAG has been previously checked.
 */
void _ha_vdiag_warning(const char *fmt, va_list argp)
{
	print_message(1, "DIAG", fmt, argp);
}

/*
 * Output a diagnostic warning.
 * Use it only if MODE_DIAG has been previously checked.
 */
void _ha_diag_warning(const char *fmt, ...)
{
	va_list argp;

	va_start(argp, fmt);
	_ha_vdiag_warning(fmt, argp);
	va_end(argp);
}

/*
 * Output a diagnostic warning. Do nothing of MODE_DIAG is not on.
 */
void ha_diag_warning(const char *fmt, ...)
{
	va_list argp;

	if (global.mode & MODE_DIAG) {
		va_start(argp, fmt);
		_ha_vdiag_warning(fmt, argp);
		va_end(argp);
	}
}

/*
 * Displays the message on stderr with the pid.
 */
void ha_notice(const char *fmt, ...)
{
	va_list argp;

	if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE) ||
	    !(global.mode & MODE_STARTING)) {
		va_start(argp, fmt);
		print_message(1, "NOTICE", fmt, argp);
		va_end(argp);
	}
}

/*
 * Displays the message on <out> only if quiet mode is not set.
 */
void qfprintf(FILE *out, const char *fmt, ...)
{
	va_list argp;

	if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) {
		va_start(argp, fmt);
		vfprintf(out, fmt, argp);
		fflush(out);
		va_end(argp);
	}
}


/* parse the "show startup-logs" command, returns 1 if a message is returned, otherwise zero */
static int cli_parse_show_startup_logs(char **args, char *payload, struct appctx *appctx, void *private)
{
	if (!cli_has_level(appctx, ACCESS_LVL_OPER))
		return 1;

	if (!startup_logs)
		return cli_msg(appctx, LOG_INFO, "\n"); // nothing to print

	return ring_attach_cli(startup_logs, appctx, 0);
}

/* register cli keywords */
static struct cli_kw_list cli_kws = {{ },{
	{ { "show", "startup-logs",  NULL }, "show startup-logs                       : report logs emitted during HAProxy startup", cli_parse_show_startup_logs, NULL, NULL, NULL, ACCESS_MASTER },
	{{},}
}};

INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws);


static void deinit_errors_buffers()
{
	ring_free(_HA_ATOMIC_XCHG(&startup_logs, NULL));
	ha_free(&usermsgs_buf.area);
	ha_free(&usermsgs_ctx.str.area);
}

/* errors might be used in threads and even before forking, thus 2 deinit */
REGISTER_PER_THREAD_FREE(deinit_errors_buffers);
REGISTER_POST_DEINIT(deinit_errors_buffers);
