/*
 * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com>
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */
//config:config HEXEDIT
//config:	bool "hexedit (21 kb)"
//config:	default y
//config:	help
//config:	Edit file in hexadecimal.

//applet:IF_HEXEDIT(APPLET(hexedit, BB_DIR_USR_BIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_HEXEDIT) += hexedit.o

#include "libbb.h"

#define ESC		"\033"
#define HOME		ESC"[H"
#define CLEAR		ESC"[J"
#define CLEAR_TILL_EOL	ESC"[K"
#define SET_ALT_SCR	ESC"[?1049h"
#define POP_ALT_SCR	ESC"[?1049l"

#undef CTRL
#define CTRL(c)  ((c) & (uint8_t)~0x60)

struct globals {
	smallint half;
	smallint in_read_key;
	int fd;
	unsigned height;
	unsigned row;
	IF_VARIABLE_ARCH_PAGESIZE(unsigned pagesize;)
#define G_pagesize cached_pagesize(G.pagesize)
	uint8_t *baseaddr;
	uint8_t *current_byte;
	uint8_t *eof_byte;
	off_t size;
	off_t offset;
	/* needs to be zero-inited, thus keeping it in G: */
	char read_key_buffer[KEYCODE_BUFFER_SIZE];
	struct termios orig_termios;
};
#define G (*ptr_to_globals)
#define INIT_G() do { \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
} while (0)

/* hopefully there aren't arches with PAGE_SIZE > 64k */
#define G_mapsize  (64*1024)

/* "12ef5670 (xx )*16 _1_3_5_7_9abcdef\n"NUL */
#define LINEBUF_SIZE (8 + 1 + 3*16 + 16 + 1 + 1 /*paranoia:*/ + 13)

static void restore_term(void)
{
	tcsetattr_stdin_TCSANOW(&G.orig_termios);
	printf(POP_ALT_SCR);
	fflush_all();
}

static void sig_catcher(int sig)
{
	if (!G.in_read_key) {
		/* now it's not safe to do I/O, just inform the main loop */
		bb_got_signal = sig;
		return;
	}
	restore_term();
	kill_myself_with_sig(sig);
}

static int format_line(char *hex, uint8_t *data, off_t offset)
{
	int ofs_pos;
	char *text;
	uint8_t *end, *end1;

#if 1
	/* Can be more than 4Gb, thus >8 chars, thus use a variable - don't assume 8! */
	ofs_pos = sprintf(hex, "%08"OFF_FMT"x ", offset);
#else
	if (offset <= 0xffff)
		ofs_pos = sprintf(hex, "%04"OFF_FMT"x ", offset);
	else
		ofs_pos = sprintf(hex, "%08"OFF_FMT"x ", offset);
#endif
	hex += ofs_pos;

	text = hex + 16 * 3;
	end1 = data + 15;
	if ((G.size - offset) > 0) {
		end = end1;
		if ((G.size - offset) <= 15)
			end = data + (G.size - offset) - 1;
		while (data <= end) {
			uint8_t c = *data++;
			*hex++ = bb_hexdigits_upcase[c >> 4];
			*hex++ = bb_hexdigits_upcase[c & 0xf];
			*hex++ = ' ';
			if (c < ' ' || c > 0x7e)
				c = '.';
			*text++ = c;
		}
	}
	while (data <= end1) {
		*hex++ = ' ';
		*hex++ = ' ';
		*hex++ = ' ';
		*text++ = ' ';
		data++;
	}
	*text = '\0';

	return ofs_pos;
}

static void redraw(unsigned cursor)
{
	uint8_t *data;
	off_t offset;
	unsigned i, pos;

	printf(HOME CLEAR);

	/* if cursor is past end of screen, how many lines to move down? */
	i = (cursor / 16) - G.height + 1;
	if ((int)i < 0)
		i = 0;

	data = G.baseaddr + i * 16;
	offset = G.offset + i * 16;
	cursor -= i * 16;
	pos = i = 0;
	while (i < G.height) {
		char buf[LINEBUF_SIZE];
		pos = format_line(buf, data, offset);
		printf(
			"\r\n%s" + (!i) * 2, /* print \r\n only on 2nd line and later */
			buf
		);
		data += 16;
		offset += 16;
		i++;
	}

	G.row = cursor / 16;
	printf(ESC"[%u;%uH", 1 + G.row, 1 + pos + (cursor & 0xf) * 3);
}

static void redraw_cur_line(void)
{
	char buf[LINEBUF_SIZE];
	uint8_t *data;
	off_t offset;
	int column;

	column = (0xf & (uintptr_t)G.current_byte);
	data = G.current_byte - column;
	offset = G.offset + (data - G.baseaddr);

	column = column*3 + G.half;
	column += format_line(buf, data, offset);
	printf("%s"
		"\r"
		"%.*s",
		buf + column,
		column, buf
	);
}

/* if remappers return 0, no change was done */
static int remap(unsigned cur_pos)
{
	if (G.baseaddr)
		munmap(G.baseaddr, G_mapsize);

	G.baseaddr = mmap(NULL,
		G_mapsize,
		PROT_READ | PROT_WRITE,
		MAP_SHARED,
		G.fd,
		G.offset
	);
	if (G.baseaddr == MAP_FAILED) {
		restore_term();
		bb_simple_perror_msg_and_die("mmap");
	}

	G.current_byte = G.baseaddr + cur_pos;

	G.eof_byte = G.baseaddr + G_mapsize;
	if ((G.size - G.offset) < G_mapsize) {
		/* mapping covers tail of the file */
		/* we do have a mapped byte which is past eof */
		G.eof_byte = G.baseaddr + (G.size - G.offset);
	}
	return 1;
}
static int move_mapping_further(void)
{
	unsigned pos;
	unsigned pagesize;

	if ((G.size - G.offset) < G_mapsize)
		return 0; /* can't move mapping even further, it's at the end already */

	pagesize = G_pagesize; /* constant on most arches */
	pos = G.current_byte - G.baseaddr;
	if (pos >= pagesize) {
		/* move offset up until current position is in 1st page */
		do {
			G.offset += pagesize;
			if (G.offset == 0) { /* whoops */
				G.offset -= pagesize;
				break;
			}
			pos -= pagesize;
		} while (pos >= pagesize);
		return remap(pos);
	}
	return 0;
}
static int move_mapping_lower(void)
{
	unsigned pos;
	unsigned pagesize;

	if (G.offset == 0)
		return 0; /* we are at 0 already */

	pagesize = G_pagesize; /* constant on most arches */
	pos = G.current_byte - G.baseaddr;

	/* move offset down until current position is in last page */
	pos += pagesize;
	while (pos < G_mapsize) {
		pos += pagesize;
		G.offset -= pagesize;
		if (G.offset == 0)
			break;
	}
	pos -= pagesize;

	return remap(pos);
}

//usage:#define hexedit_trivial_usage
//usage:	"FILE"
//usage:#define hexedit_full_usage "\n\n"
//usage:	"Edit FILE in hexadecimal"
int hexedit_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int hexedit_main(int argc UNUSED_PARAM, char **argv)
{
	INIT_G();
	INIT_PAGESIZE(G.pagesize);

	get_terminal_width_height(-1, NULL, &G.height);
	if (1) {
		/* reduce number of write() syscalls while PgUp/Down: fully buffered output */
		unsigned sz = (G.height | 0xf) * LINEBUF_SIZE;
		setvbuf(stdout, xmalloc(sz), _IOFBF, sz);
	}

	getopt32(argv, "^" "" "\0" "=1"/*one arg*/);
	argv += optind;

	G.fd = xopen(*argv, O_RDWR);
	G.size = xlseek(G.fd, 0, SEEK_END);

	/* TERMIOS_RAW_CRNL suppresses \n -> \r\n translation, helps with down-arrow */
	printf(SET_ALT_SCR);
	set_termios_to_raw(STDIN_FILENO, &G.orig_termios, TERMIOS_RAW_CRNL);
	bb_signals(BB_FATAL_SIGS, sig_catcher);

	remap(0);
	redraw(0);

//TODO: //Home/End: start/end of line; '<'/'>': start/end of file
	//Backspace: undo
	//Ctrl-L: redraw
	//Ctrl-Z: suspend
	//'/', Ctrl-S: search
//TODO: detect window resize

	for (;;) {
		unsigned cnt;
		int32_t key = key; /* for compiler */
		uint8_t byte;

		fflush_all();
		G.in_read_key = 1;
		if (!bb_got_signal)
			key = safe_read_key(STDIN_FILENO, G.read_key_buffer, -1);
		G.in_read_key = 0;
		if (bb_got_signal)
			key = CTRL('X');

		cnt = 1;
		if ((unsigned)(key - 'A') <= 'Z' - 'A')
			key |= 0x20; /* convert A-Z to a-z */
		switch (key) {
		case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
			/* convert to '0'+10...15 */
			key = key - ('a' - '0' - 10);
			/* fall through */
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			if (G.current_byte == G.eof_byte) {
				if (!move_mapping_further()) {
					/* already at EOF; extend the file */
					if (++G.size <= 0 /* overflow? */
					 || ftruncate(G.fd, G.size) != 0 /* error extending? (e.g. block dev) */
					) {
						G.size--;
						break;
					}
					G.eof_byte++;
				}
			}
			key -= '0';
			byte = *G.current_byte & 0xf0;
			if (!G.half) {
				byte = *G.current_byte & 0x0f;
				key <<= 4;
			}
			*G.current_byte = byte + key;
			/* can't just print one updated hex char: need to update right-hand ASCII too */
			redraw_cur_line();
			/* fall through */
		case KEYCODE_RIGHT:
			if (G.current_byte == G.eof_byte)
				break; /* eof - don't allow going past it */
			byte = *G.current_byte;
			if (!G.half) {
				G.half = 1;
				putchar(bb_hexdigits_upcase[byte >> 4]);
			} else {
				G.half = 0;
				G.current_byte++;
				if ((0xf & (uintptr_t)G.current_byte) == 0) {
					/* rightmost pos, wrap to next line */
					if (G.current_byte == G.eof_byte)
						move_mapping_further();
					printf(ESC"[46D"); /* cursor left 3*15 + 1 chars */
					goto down;
				}
				putchar(bb_hexdigits_upcase[byte & 0xf]);
				putchar(' ');
			}
			break;
		case KEYCODE_PAGEDOWN:
			cnt = G.height;
		case KEYCODE_DOWN:
 k_down:
			G.current_byte += 16;
			if (G.current_byte >= G.eof_byte) {
				move_mapping_further();
				if (G.current_byte > G.eof_byte) {
					/* _after_ eof - don't allow this */
					G.current_byte -= 16;
					if (G.current_byte < G.baseaddr)
						move_mapping_lower();
					break;
				}
			}
 down:
			putchar('\n'); /* down one line, possibly scroll screen */
			G.row++;
			if (G.row >= G.height) {
				G.row--;
				redraw_cur_line();
			}
			if (--cnt)
				goto k_down;
			break;

		case KEYCODE_LEFT:
			if (G.half) {
				G.half = 0;
				printf(ESC"[D");
				break;
			}
			if ((0xf & (uintptr_t)G.current_byte) == 0) {
				/* leftmost pos, wrap to prev line */
				if (G.current_byte == G.baseaddr) {
					if (!move_mapping_lower())
						break; /* first line, don't do anything */
				}
				G.half = 1;
				G.current_byte--;
				printf(ESC"[46C"); /* cursor right 3*15 + 1 chars */
				goto up;
			}
			G.half = 1;
			G.current_byte--;
			printf(ESC"[2D");
			break;
		case KEYCODE_PAGEUP:
			cnt = G.height;
		case KEYCODE_UP:
 k_up:
			if ((G.current_byte - G.baseaddr) < 16) {
				if (!move_mapping_lower())
					break; /* already at 0, stop */
			}
			G.current_byte -= 16;
 up:
			if (G.row != 0) {
				G.row--;
				printf(ESC"[A"); /* up (won't scroll) */
			} else {
				//printf(ESC"[T"); /* scroll up */ - not implemented on Linux VT!
				printf(ESC"M"); /* scroll up */
				redraw_cur_line();
			}
			if (--cnt)
				goto k_up;
			break;

		case '\n':
		case '\r':
			/* [Enter]: goto specified position */
			{
				char buf[sizeof(G.offset)*3 + 4];
				printf(ESC"[999;1H" CLEAR_TILL_EOL); /* go to last line */
				if (read_line_input(NULL, "Go to (dec,0Xhex,0oct): ", buf, sizeof(buf)) > 0) {
					off_t t;
					unsigned cursor;

					t = bb_strtoull(buf, NULL, 0);
					if (t >= G.size)
						t = G.size - 1;
					cursor = t & (G_pagesize - 1);
					t -= cursor;
					if (t < 0)
						cursor = t = 0;
					if (t != 0 && cursor < 0x1ff) {
						/* very close to end of page, possibly to EOF */
						/* move one page lower */
						t -= G_pagesize;
						cursor += G_pagesize;
					}
					G.offset = t;
					remap(cursor);
					redraw(cursor);
					break;
				}
				/* ^C/EOF/error: fall through to exiting */
			}
		case CTRL('X'):
			restore_term();
			return EXIT_SUCCESS;
		} /* switch */
	} /* for (;;) */

	/* not reached */
	return EXIT_SUCCESS;
}
