/* vi: set sw=4 ts=4:
 *
 * Apply a "universal" diff.
 * Adapted from toybox's patch implementation.
 *
 * Copyright 2007 Rob Landley <rob@landley.net>
 *
 * see http://www.opengroup.org/onlinepubs/009695399/utilities/patch.html
 * (But only does -u, because who still cares about "ed"?)
 *
 * TODO:
 * -b backup
 * -l treat all whitespace as a single space
 * -d chdir first
 * -D define wrap #ifdef and #ifndef around changes
 * -o outfile output here instead of in place
 * -r rejectfile write rejected hunks to this file
 * --dry-run (regression!)
 *
 * -f force (no questions asked)
 * -F fuzz (number, default 2)
 * [file] which file to patch
 */

//config:config PATCH
//config:	bool "patch (9.1 kb)"
//config:	default y
//config:	help
//config:	Apply a unified diff formatted patch.

//applet:IF_PATCH(APPLET(patch, BB_DIR_USR_BIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_PATCH) += patch.o

//usage:#define patch_trivial_usage
//usage:       "[OPTIONS] [ORIGFILE [PATCHFILE]]"
//usage:#define patch_full_usage "\n\n"
//usage:	IF_LONG_OPTS(
//usage:       "	-p,--strip N		Strip N leading components from file names"
//usage:     "\n	-i,--input DIFF		Read DIFF instead of stdin"
//usage:     "\n	-R,--reverse		Reverse patch"
//usage:     "\n	-N,--forward		Ignore already applied patches"
/*usage:     "\n	--dry-run		Don't actually change files" - TODO */
//usage:     "\n	-E,--remove-empty-files	Remove output files if they become empty"
//usage:	)
//usage:	IF_NOT_LONG_OPTS(
//usage:       "	-p N	Strip N leading components from file names"
//usage:     "\n	-i DIFF	Read DIFF instead of stdin"
//usage:     "\n	-R	Reverse patch"
//usage:     "\n	-N	Ignore already applied patches"
//usage:     "\n	-E	Remove output files if they become empty"
//usage:	)
/* -u "interpret as unified diff" is supported but not documented: this info is not useful for --help */
/* -x "debug" is supported but does nothing */
//usage:
//usage:#define patch_example_usage
//usage:       "$ patch -p1 < example.diff\n"
//usage:       "$ patch -p0 -i example.diff"

#include "libbb.h"


// libbb candidate?

struct double_list {
	struct double_list *next;
	struct double_list *prev;
	char *data;
};

// Free all the elements of a linked list
// Call freeit() on each element before freeing it.
static void dlist_free(struct double_list *list, void (*freeit)(void *data))
{
	while (list) {
		void *pop = list;
		list = list->next;
		freeit(pop);
		// Bail out also if list is circular.
		if (list == pop) break;
	}
}

// Add an entry before "list" element in (circular) doubly linked list
static struct double_list *dlist_add(struct double_list **list, char *data)
{
	struct double_list *llist;
	struct double_list *line = xmalloc(sizeof(*line));

	line->data = data;
	llist = *list;
	if (llist) {
		struct double_list *p;
		line->next = llist;
		p = line->prev = llist->prev;
		// (list is circular, we assume p is never NULL)
		p->next = line;
		llist->prev = line;
	} else
		*list = line->next = line->prev = line;

	return line;
}


struct globals {
	char *infile;
	long prefix;

	struct double_list *current_hunk;

	long oldline, oldlen, newline, newlen;
	long linenum;
	int context, state, hunknum;
	int filein, fileout;
	char *tempname;

	int exitval;
};
#define TT (*ptr_to_globals)
#define INIT_TT() do { \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(TT))); \
} while (0)


#define FLAG_STR "Rup:i:NEx"
/* FLAG_REVERSE must be == 1! Code uses this fact. */
#define FLAG_REVERSE (1 << 0)
#define FLAG_u       (1 << 1)
#define FLAG_PATHLEN (1 << 2)
#define FLAG_INPUT   (1 << 3)
#define FLAG_IGNORE  (1 << 4)
#define FLAG_RMEMPTY (1 << 5)
/* Enable this bit and use -x for debug output: */
#define FLAG_DEBUG   (0 << 6)

// Dispose of a line of input, either by writing it out or discarding it.

// state < 2: just free
// state = 2: write whole line to stderr
// state = 3: write whole line to fileout
// state > 3: write line+1 to fileout when *line != state

#define PATCH_DEBUG (option_mask32 & FLAG_DEBUG)

static void do_line(void *data)
{
	struct double_list *dlist = data;

	if (TT.state>1 && *dlist->data != TT.state)
		fdprintf(TT.state == 2 ? 2 : TT.fileout,
			"%s\n", dlist->data+(TT.state>3 ? 1 : 0));

	if (PATCH_DEBUG) fdprintf(2, "DO %d: %s\n", TT.state, dlist->data);

	free(dlist->data);
	free(dlist);
}

static void finish_oldfile(void)
{
	if (TT.tempname) {
		// Copy the rest of the data and replace the original with the copy.
		char *temp;

		if (TT.filein != -1) {
			bb_copyfd_eof(TT.filein, TT.fileout);
			xclose(TT.filein);
		}
		xclose(TT.fileout);

		temp = xstrdup(TT.tempname);
		temp[strlen(temp) - 6] = '\0';
		rename(TT.tempname, temp);
		free(temp);

		free(TT.tempname);
		TT.tempname = NULL;
	}
	TT.fileout = TT.filein = -1;
}

static void fail_hunk(void)
{
	if (!TT.current_hunk) return;

	fdprintf(2, "Hunk %d FAILED %ld/%ld.\n", TT.hunknum, TT.oldline, TT.newline);
	TT.exitval = 1;

	// If we got to this point, we've seeked to the end.  Discard changes to
	// this file and advance to next file.

	TT.state = 2;
	TT.current_hunk->prev->next = NULL;
	dlist_free(TT.current_hunk, do_line);
	TT.current_hunk = NULL;

	// Abort the copy and delete the temporary file.
	close(TT.filein);
	close(TT.fileout);
	unlink(TT.tempname);
	free(TT.tempname);
	TT.tempname = NULL;

	TT.state = 0;
}

// Given a hunk of a unified diff, make the appropriate change to the file.
// This does not use the location information, but instead treats a hunk
// as a sort of regex.  Copies data from input to output until it finds
// the change to be made, then outputs the changed data and returns.
// (Finding EOF first is an error.)  This is a single pass operation, so
// multiple hunks must occur in order in the file.

static int apply_one_hunk(void)
{
	struct double_list *plist, *buf = NULL, *check;
	int matcheof = 0, reverse = option_mask32 & FLAG_REVERSE, backwarn = 0;
	/* Do we try "dummy" revert to check whether
	 * to silently skip this hunk? Used to implement -N.
	 */
	int dummy_revert = 0;

	// Break doubly linked list so we can use singly linked traversal function.
	TT.current_hunk->prev->next = NULL;

	// Match EOF if there aren't as many ending context lines as beginning
	for (plist = TT.current_hunk; plist; plist = plist->next) {
		if (plist->data[0]==' ') matcheof++;
		else matcheof = 0;
		if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data);
	}
	matcheof = !matcheof || matcheof < TT.context;

	if (PATCH_DEBUG) fdprintf(2,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N');

	// Loop through input data searching for this hunk.  Match all context
	// lines and all lines to be removed until we've found the end of a
	// complete hunk.
	plist = TT.current_hunk;
	buf = NULL;
	if (reverse ? TT.oldlen : TT.newlen) for (;;) {
		char *data = xmalloc_reads(TT.filein, NULL);

		TT.linenum++;

		// Figure out which line of hunk to compare with next.  (Skip lines
		// of the hunk we'd be adding.)
		while (plist && *plist->data == "+-"[reverse]) {
			if (data && strcmp(data, plist->data+1) == 0) {
				if (!backwarn) {
					backwarn = TT.linenum;
					if (option_mask32 & FLAG_IGNORE) {
						dummy_revert = 1;
						reverse ^= 1;
						continue;
					}
				}
			}
			plist = plist->next;
		}

		// Is this EOF?
		if (!data) {
			if (PATCH_DEBUG) fdprintf(2, "INEOF\n");

			// Does this hunk need to match EOF?
			if (!plist && matcheof) break;

			if (backwarn)
				fdprintf(2,"Possibly reversed hunk %d at %ld\n",
					TT.hunknum, TT.linenum);

			// File ended before we found a place for this hunk.
			fail_hunk();
			goto done;
		}

		if (PATCH_DEBUG) fdprintf(2, "IN: %s\n", data);
		check = dlist_add(&buf, data);

		// Compare this line with next expected line of hunk.
		// todo: teach the strcmp() to ignore whitespace.

		// A match can fail because the next line doesn't match, or because
		// we hit the end of a hunk that needed EOF, and this isn't EOF.

		// If match failed, flush first line of buffered data and
		// recheck buffered data for a new match until we find one or run
		// out of buffer.

		for (;;) {
			while (plist && *plist->data == "+-"[reverse]) {
				if (strcmp(check->data, plist->data+1) == 0
				 && !backwarn
				) {
					backwarn = TT.linenum;
					if (option_mask32 & FLAG_IGNORE) {
						dummy_revert = 1;
						reverse ^= 1;
					}
				}
				plist = plist->next;
			}
			if (!plist || strcmp(check->data, plist->data+1)) {
				// Match failed.  Write out first line of buffered data and
				// recheck remaining buffered data for a new match.

				if (PATCH_DEBUG)
					fdprintf(2, "NOT: %s\n", plist ? plist->data : "EOF");

				TT.state = 3;
				check = buf;
				buf = buf->next;
				check->prev->next = buf;
				buf->prev = check->prev;
				do_line(check);
				plist = TT.current_hunk;

				// If we've reached the end of the buffer without confirming a
				// match, read more lines.
				if (check == buf) {
					buf = NULL;
					break;
				}
				check = buf;
			} else {
				if (PATCH_DEBUG)
					fdprintf(2, "MAYBE: %s\n", plist->data);
				// This line matches.  Advance plist, detect successful match.
				plist = plist->next;
				if (!plist && !matcheof) goto out;
				check = check->next;
				if (check == buf) break;
			}
		}
	}
out:
	// We have a match.  Emit changed data.
	TT.state = "-+"[reverse ^ dummy_revert];
	dlist_free(TT.current_hunk, do_line);
	TT.current_hunk = NULL;
	TT.state = 1;
done:
	if (buf) {
		buf->prev->next = NULL;
		dlist_free(buf, do_line);
	}

	return TT.state;
}

// Read a patch file and find hunks, opening/creating/deleting files.
// Call apply_one_hunk() on each hunk.

// state 0: Not in a hunk, look for +++.
// state 1: Found +++ file indicator, look for @@
// state 2: In hunk: counting initial context lines
// state 3: In hunk: getting body
// Like GNU patch, we don't require a --- line before the +++, and
// also allow the --- after the +++ line.

int patch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int patch_main(int argc UNUSED_PARAM, char **argv)
{
	int opts;
	int reverse, state = 0;
	char *oldname = NULL, *newname = NULL;
	char *opt_p, *opt_i;
	long oldlen = oldlen; /* for compiler */
	long newlen = newlen; /* for compiler */

	INIT_TT();

	opts = getopt32(argv, FLAG_STR, &opt_p, &opt_i);
	argv += optind;
	reverse = opts & FLAG_REVERSE;
	TT.prefix = (opts & FLAG_PATHLEN) ? xatoi(opt_p) : 0; // can be negative!
	TT.filein = TT.fileout = -1;
	if (opts & FLAG_INPUT) {
		xmove_fd(xopen_stdin(opt_i), STDIN_FILENO);
	} else {
		if (argv[0] && argv[1]) {
			xmove_fd(xopen_stdin(argv[1]), STDIN_FILENO);
		}
	}

	// Loop through the lines in the patch
	for(;;) {
		char *patchline;

		patchline = xmalloc_fgetline(stdin);
		if (!patchline) break;

		// Other versions of patch accept damaged patches,
		// so we need to also.
		if (!*patchline) {
			free(patchline);
			patchline = xstrdup(" ");
		}

		// Are we assembling a hunk?
		if (state >= 2) {
			if (*patchline==' ' || *patchline=='+' || *patchline=='-') {
				dlist_add(&TT.current_hunk, patchline);

				if (*patchline != '+') oldlen--;
				if (*patchline != '-') newlen--;

				// Context line?
				if (*patchline==' ' && state==2) TT.context++;
				else state=3;

				// If we've consumed all expected hunk lines, apply the hunk.

				if (!oldlen && !newlen) state = apply_one_hunk();
				continue;
			}
			fail_hunk();
			state = 0;
			continue;
		}

		// Open a new file?
		if (is_prefixed_with(patchline, "--- ") || is_prefixed_with(patchline, "+++ ")) {
			char *s, **name = reverse ? &newname : &oldname;
			int i;

			if (*patchline == '+') {
				name = reverse ? &oldname : &newname;
				state = 1;
			}

			finish_oldfile();

			if (!argv[0]) {
				free(*name);
				// Trim date from end of filename (if any).  We don't care.
				for (s = patchline+4; *s && *s!='\t'; s++)
					if (*s=='\\' && s[1]) s++;
				i = atoi(s);
				if (i>1900 && i<=1970)
					*name = xstrdup("/dev/null");
				else {
					*s = 0;
					*name = xstrdup(patchline+4);
				}
			}

			// We defer actually opening the file because svn produces broken
			// patches that don't signal they want to create a new file the
			// way the patch man page says, so you have to read the first hunk
			// and _guess_.

		// Start a new hunk?  Usually @@ -oldline,oldlen +newline,newlen @@
		// but a missing ,value means the value is 1.
		} else if (state == 1 && is_prefixed_with(patchline, "@@ -")) {
			int i;
			char *s = patchline+4;

			// Read oldline[,oldlen] +newline[,newlen]

			TT.oldlen = oldlen = TT.newlen = newlen = 1;
			TT.oldline = strtol(s, &s, 10);
			if (*s == ',') TT.oldlen = oldlen = strtol(s+1, &s, 10);
			TT.newline = strtol(s+2, &s, 10);
			if (*s == ',') TT.newlen = newlen = strtol(s+1, &s, 10);

			if (oldlen < 1 && newlen < 1)
				bb_error_msg_and_die("Really? %s", patchline);

			TT.context = 0;
			state = 2;

			// If the --- line is missing or malformed, either oldname
			// or (for -R) newname could be NULL -- but not both.  Like
			// GNU patch, proceed based on the +++ line, and avoid SEGVs.
			if (!oldname)
				oldname = xstrdup("MISSING_FILENAME");
			if (!newname)
				newname = xstrdup("MISSING_FILENAME");

			// If this is the first hunk, open the file.
			if (TT.filein == -1) {
				int oldsum, newsum, empty = 0;
				char *name;

				oldsum = TT.oldline + oldlen;
				newsum = TT.newline + newlen;

				name = reverse ? oldname : newname;

				// We're deleting oldname if new file is /dev/null (before -p)
				// or if new hunk is empty (zero context) after patching
				if (strcmp(name, "/dev/null") == 0 || !(reverse ? oldsum : newsum)) {
					name = reverse ? newname : oldname;
					empty = 1;
				}

				// Handle -p path truncation.
				for (i = 0, s = name; *s;) {
					if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i)
						break;
					if (*s++ != '/')
						continue;
					while (*s == '/')
						s++;
					i++;
					name = s;
				}
				// If "patch FILE_TO_PATCH", completely ignore name from patch
				if (argv[0])
					name = argv[0];

				if (empty) {
					// File is empty after the patches have been applied
					state = 0;
					if (option_mask32 & FLAG_RMEMPTY) {
						// If flag -E or --remove-empty-files is set
						printf("removing %s\n", name);
						xunlink(name);
					} else {
						printf("patching file %s\n", name);
						xclose(xopen(name, O_WRONLY | O_TRUNC));
					}
				// If we've got a file to open, do so.
				} else if (!(option_mask32 & FLAG_PATHLEN) || i <= TT.prefix) {
					struct stat statbuf;

					// If the old file was null, we're creating a new one.
					if (strcmp(oldname, "/dev/null") == 0 || !oldsum) {
						printf("creating %s\n", name);
						s = strrchr(name, '/');
						if (s) {
							*s = 0;
							bb_make_directory(name, -1, FILEUTILS_RECUR);
							*s = '/';
						}
						TT.filein = xopen(name, O_CREAT|O_EXCL|O_RDWR);
					} else {
						printf("patching file %s\n", name);
						TT.filein = xopen(name, O_RDONLY);
					}

					TT.tempname = xasprintf("%sXXXXXX", name);
					TT.fileout = xmkstemp(TT.tempname);
					// Set permissions of output file
					fstat(TT.filein, &statbuf);
					fchmod(TT.fileout, statbuf.st_mode);

					TT.linenum = 0;
					TT.hunknum = 0;
				}
			}

			TT.hunknum++;

			continue;
		}

		// If we didn't continue above, discard this line.
		free(patchline);
	}

	finish_oldfile();

	if (ENABLE_FEATURE_CLEAN_UP) {
		free(oldname);
		free(newname);
	}

	return TT.exitval;
}
