/*
 * post-mortem ring reader for haproxy
 *
 * Copyright (C) 2022 Willy Tarreau <w@1wt.eu>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
/* we do not implement BUG_ON() */
#undef DEBUG_STRICT

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

#include <haproxy/api.h>
#include <haproxy/buf.h>
#include <haproxy/ring.h>

int force = 0; // force access to a different layout
int lfremap = 0; // remap LF in traces
int repair = 0; // repair file


/* display the message and exit with the code */
__attribute__((noreturn)) void die(int code, const char *format, ...)
{
	va_list args;

	if (format) {
		va_start(args, format);
		vfprintf(stderr, format, args);
		va_end(args);
	}
	exit(code);
}

/* display the usage message and exit with the code */
__attribute__((noreturn)) void usage(int code, const char *arg0)
{
	die(code,
	    "Usage: %s [options]* <file>\n"
	    "\n"
	    "options :\n"
	    "  -f           : force accessing a non-matching layout for 'ring struct'\n"
	    "  -l           : replace LF in contents with CR VT\n"
	    "  -r           : \"repair\" corrupted file (actively search for message boundaries)\n"
	    "\n"
	    "", arg0);
}

/* This function dumps all events from the ring whose pointer is in <p0> into
 * the appctx's output buffer, and takes from <o0> the seek offset into the
 * buffer's history (0 for oldest known event). It looks at <i0> for boolean
 * options: bit0 means it must wait for new data or any key to be pressed. Bit1
 * means it must seek directly to the end to wait for new contents. It returns
 * 0 if the output buffer or events are missing is full and it needs to be
 * called again, otherwise non-zero. It is meant to be used with
 * cli_release_show_ring() to clean up.
 */
int dump_ring(struct ring *ring, size_t ofs, int flags)
{
	struct buffer buf;
	uint64_t msg_len = 0;
	size_t len, cnt;
	const char *blk1 = NULL, *blk2 = NULL, *p;
	size_t len1 = 0, len2 = 0, bl;

	/* Explanation: the storage area in the writing process starts after
	 * the end of the structure. Since the whole area is mmapped(), we know
	 * it starts at 0 mod 4096, hence the buf->area pointer's 12 LSB point
	 * to the relative offset of the storage area. As there will always be
	 * users using the wrong version of the tool with a dump, we need to
	 * run a few checks first. After that we'll create our own buffer
	 * descriptor matching that area.
	 */
	if ((((long)ring->buf.area) & 4095) != sizeof(*ring)) {
		if (!force) {
			fprintf(stderr, "FATAL: header in file is %ld bytes long vs %ld expected!\n",
				(((long)ring->buf.area) & 4095),
				(long)sizeof(*ring));
			exit(1);
		}
		else {
			fprintf(stderr, "WARNING: header in file is %ld bytes long vs %ld expected!\n",
				(((long)ring->buf.area) & 4095),
				(long)sizeof(*ring));
		}
		/* maybe we could emit a warning at least ? */
	}

	/* Now make our own buffer pointing to that area */
	buf = b_make(((void *)ring + (((long)ring->buf.area) & 4095)),
		     ring->buf.size, ring->buf.head, ring->buf.data);

	/* explanation for the initialization below: it would be better to do
	 * this in the parsing function but this would occasionally result in
	 * dropped events because we'd take a reference on the oldest message
	 * and keep it while being scheduled. Thus instead let's take it the
	 * first time we enter here so that we have a chance to pass many
	 * existing messages before grabbing a reference to a location. This
	 * value cannot be produced after initialization.
	 */
	if (unlikely(ofs == ~0)) {
		ofs = 0;

		/* going to the end means looking at tail-1 */
		ofs = (flags & RING_WF_SEEK_NEW) ? buf.data - 1 : 0;

		//HA_ATOMIC_INC(b_peek(&buf, ofs));
	}

	while (1) {
		//HA_RWLOCK_RDLOCK(LOGSRV_LOCK, &ring->lock);

		if (ofs >= buf.size) {
			fprintf(stderr, "FATAL error at %d\n", __LINE__);
			return 1;
		}
		//HA_ATOMIC_DEC(b_peek(&buf, ofs));

		/* in this loop, ofs always points to the counter byte that precedes
		 * the message so that we can take our reference there if we have to
		 * stop before the end.
		 */
		while (ofs + 1 < b_data(&buf)) {
			if (unlikely(repair && *b_peek(&buf, ofs))) {
				/* in repair mode we consider that we could have landed
				 * in the middle of a message so we skip all bytes till
				 * the next zero.
				 */
				ofs++;
				continue;
			}
			cnt = 1;
			len = b_peek_varint(&buf, ofs + cnt, &msg_len);
			if (!len)
				break;
			cnt += len;

			if (msg_len + ofs + cnt + 1 > buf.data) {
				fprintf(stderr, "FATAL error at %d\n", __LINE__);
				return 1;
			}

			len = b_getblk_nc(&buf, &blk1, &len1, &blk2, &len2, ofs + cnt, msg_len);
			if (!lfremap) {
				if (len > 0 && len1)
					fwrite(blk1, len1, 1, stdout);
				if (len > 1 && len2)
					fwrite(blk2, len2, 1, stdout);
			} else {
				while (len > 0) {
					for (; len1; p++) {
						p = memchr(blk1, '\n', len1);
						if (!p || p > blk1) {
							bl = p ? p - blk1 : len1;
							fwrite(blk1, bl, 1, stdout);
							blk1 += bl;
							len1 -= bl;
						}

						if (p) {
							putchar('\r');
							putchar('\v');
							blk1++;
							len1--;
						}
					}
					len--;
					blk1 = blk2;
					len1 = len2;
				}
			}

			putchar('\n');

			ofs += cnt + msg_len;
		}

		//HA_ATOMIC_INC(b_peek(&buf, ofs));
		//HA_RWLOCK_RDUNLOCK(LOGSRV_LOCK, &ring->lock);

		if (!(flags & RING_WF_WAIT_MODE))
			break;

		/* pause 10ms before checking for new stuff */
		usleep(10000);
	}
	return 0;
}

int main(int argc, char **argv)
{
	struct ring *ring;
	struct stat statbuf;
	const char *arg0;
	int fd;

	arg0 = argv[0];
	while (argc > 1 && argv[1][0] == '-') {
		argc--; argv++;
		if (strcmp(argv[0], "-f") == 0)
			force = 1;
		else if (strcmp(argv[0], "-l") == 0)
			lfremap = 1;
		else if (strcmp(argv[0], "-r") == 0)
			repair = 1;
		else if (strcmp(argv[0], "--") == 0)
			break;
		else
			usage(1, arg0);
	}

	if (argc < 2)
		usage(1, arg0);

	fd = open(argv[1], O_RDONLY);
	if (fd < 0) {
		perror("open()");
		return 1;
	}

	if (fstat(fd, &statbuf) < 0) {
		perror("fstat()");
		return 1;
	}

	ring = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
	close(fd);

	if (ring == MAP_FAILED) {
		perror("mmap()");
		return 1;
	}

	return dump_ring(ring, ~0, 0);
}


/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */
