/* Adapted from toybox's patch. */

/* vi: set sw=4 ts=4:
 *
 * patch.c - Apply a "universal" diff.
 *
 * 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
 * -N ignore already applied
 * -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
 *
 * -E remove empty files --remove-empty-files
 * -f force (no questions asked)
 * -F fuzz (number, default 2)
 * [file] which file to patch

USE_PATCH(NEWTOY(patch, USE_TOYBOX_DEBUG("x")"up#i:R", TOYFLAG_USR|TOYFLAG_BIN))

config PATCH
	bool "patch (9.4 kb)"
	default y
	help
	  usage: patch [-i file] [-p depth] [-Ru]

	  Apply a unified diff to one or more files.

	  -i	Input file (defaults=stdin)
	  -p	number of '/' to strip from start of file paths (default=all)
	  -R	Reverse patch.
	  -u	Ignored (only handles "unified" diffs)

	  This version of patch only handles unified diffs, and only modifies
	  a file when all all hunks to that file apply.  Patch prints failed
	  hunks to stderr, and exits with nonzero status if any hunks fail.

	  A file compared against /dev/null (or with a date <= the epoch) is
	  created/deleted as appropriate.
*/
#include "libbb.h"

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

// Return the first item from the list, advancing the list (which must be called
// as &list)
static
void *TOY_llist_pop(void *list)
{
	// I'd use a void ** for the argument, and even accept the typecast in all
	// callers as documentation you need the &, except the stupid compiler
	// would then scream about type-punned pointers.  Screw it.
	void **llist = (void **)list;
	void **next = (void **)*llist;
	*llist = *next;

	return (void *)next;
}

// Free all the elements of a linked list
// if freeit!=NULL call freeit() on each element before freeing it.
static
void TOY_llist_free(void *list, void (*freeit)(void *data))
{
	while (list) {
		void *pop = TOY_llist_pop(&list);
		if (freeit) freeit(pop);
		else free(pop);

		// End doubly linked list too.
		if (list==pop) break;
	}
}

// Add an entry to the end off a doubly linked list
static
struct double_list *dlist_add(struct double_list **list, char *data)
{
	struct double_list *line = xmalloc(sizeof(struct double_list));

	line->data = data;
	if (*list) {
		line->next = *list;
		line->prev = (*list)->prev;
		(*list)->prev->next = line;
		(*list)->prev = line;
	} else *list = line->next = line->prev = line;

	return line;
}

// Ensure entire path exists.
// If mode != -1 set permissions on newly created dirs.
// Requires that path string be writable (for temporary null terminators).
static
void xmkpath(char *path, int mode)
{
	char *p, old;
	mode_t mask;
	int rc;
	struct stat st;

	for (p = path; ; p++) {
		if (!*p || *p == '/') {
			old = *p;
			*p = rc = 0;
			if (stat(path, &st) || !S_ISDIR(st.st_mode)) {
				if (mode != -1) {
					mask = umask(0);
					rc = mkdir(path, mode);
					umask(mask);
				} else rc = mkdir(path, 0777);
			}
			*p = old;
			if(rc) bb_perror_msg_and_die("mkpath '%s'", path);
		}
		if (!*p) break;
	}
}

// Slow, but small.
static
char *get_rawline(int fd, long *plen, char end)
{
	char c, *buf = NULL;
	long len = 0;

	for (;;) {
		if (1>read(fd, &c, 1)) break;
		if (!(len & 63)) buf=xrealloc(buf, len+65);
		if ((buf[len++]=c) == end) break;
	}
	if (buf) buf[len]=0;
	if (plen) *plen = len;

	return buf;
}

static
char *get_line(int fd)
{
	long len;
	char *buf = get_rawline(fd, &len, '\n');

	if (buf && buf[--len]=='\n') buf[len]=0;

	return buf;
}

// Copy the rest of in to out and close both files.
static
void xsendfile(int in, int out)
{
	long len;
	char buf[4096];

	if (in<0) return;
	for (;;) {
		len = safe_read(in, buf, 4096);
		if (len<1) break;
		xwrite(out, buf, len);
	}
}

// Copy the rest of the data and replace the original with the copy.
static
void replace_tempfile(int fdin, int fdout, char **tempname)
{
	char *temp = xstrdup(*tempname);

	temp[strlen(temp)-6]=0;
	if (fdin != -1) {
		xsendfile(fdin, fdout);
		xclose(fdin);
	}
	xclose(fdout);
	rename(*tempname, temp);
	free(*tempname);
	free(temp);
	*tempname = NULL;
}

// Open a temporary file to copy an existing file into.
static
int copy_tempfile(int fdin, char *name, char **tempname)
{
	struct stat statbuf;
	int fd;

	*tempname = xasprintf("%sXXXXXX", name);
	fd = mkstemp(*tempname);
	if(-1 == fd) bb_simple_perror_msg_and_die("no temp file");

	// Set permissions of output file
	fstat(fdin, &statbuf);
	fchmod(fd, statbuf.st_mode);

	return fd;
}

// Abort the copy and delete the temporary file.
static
void delete_tempfile(int fdin, int fdout, char **tempname)
{
	close(fdin);
	close(fdout);
	unlink(*tempname);
	free(*tempname);
	*tempname = NULL;
}



struct globals {
	char *infile;
	long prefix;

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

	// was toys.foo:
	int exitval;
};
#define TT (*ptr_to_globals)
#define INIT_TT() do { \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(TT))); \
} while (0)


//bbox had: "p:i:RN"
#define FLAG_STR "Rup:i:x"
/* 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)
//non-standard:
#define FLAG_DEBUG   (1 << 4)

// 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 = (struct double_list *)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(data);
}

static void finish_oldfile(void)
{
	if (TT.tempname) replace_tempfile(TT.filein, TT.fileout, &TT.tempname);
	TT.fileout = TT.filein = -1;
}

static void fail_hunk(void)
{
	if (!TT.current_hunk) return;
	TT.current_hunk->prev->next = 0;

	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;
	TOY_llist_free(TT.current_hunk, do_line);
	TT.current_hunk = NULL;
	delete_tempfile(TT.filein, TT.fileout, &TT.tempname);
	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;

	// 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 < 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 (TT.context) for (;;) {
		char *data = get_line(TT.filein);

		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) {
					fdprintf(2,"Possibly reversed hunk %d at %ld\n",
						TT.hunknum, TT.linenum);
					backwarn++;
				}
			}
			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;

			// File ended before we found a place for this hunk.
			fail_hunk();
			goto done;
		} else 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 (;;) {
			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->data);

				TT.state = 3;
				check = TOY_llist_pop(&buf);
				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 = 0;
					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];
	TOY_llist_free(TT.current_hunk, do_line);
	TT.current_hunk = NULL;
	TT.state = 1;
done:
	if (buf) {
		buf->prev->next = NULL;
		TOY_llist_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

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;

	INIT_TT();

	opts = getopt32(argv, FLAG_STR, &opt_p, &opt_i);
	reverse = opts & FLAG_REVERSE;
	TT.prefix = (opts & FLAG_PATHLEN) ? xatoi(opt_p) : 0; // can be negative!
	if (opts & FLAG_INPUT) TT.filepatch = xopen(opt_i, O_RDONLY);
	TT.filein = TT.fileout = -1;

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

		patchline = get_line(TT.filepatch);
		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 != '+') TT.oldlen--;
				if (*patchline != '-') TT.newlen--;

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

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

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

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

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

			free(*name);
			finish_oldfile();

			// 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?
		} else if (state == 1 && !strncmp("@@ -", patchline, 4)) {
			int i;

			i = sscanf(patchline+4, "%ld,%ld +%ld,%ld", &TT.oldline,
						&TT.oldlen, &TT.newline, &TT.newlen);
			if (i != 4)
				bb_error_msg_and_die("corrupt hunk %d at %ld", TT.hunknum, TT.linenum);

			TT.context = 0;
			state = 2;

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

				oldsum = TT.oldline + TT.oldlen;
				newsum = TT.newline + TT.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;
					del++;
				}

				// handle -p path truncation.
				for (i=0, s = name; *s;) {
					if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break;
					if (*(s++)=='/') {
						name = s;
						i++;
					}
				}

				if (del) {
					printf("removing %s\n", name);
					xunlink(name);
					state = 0;
				// If we've got a file to open, do so.
				} else if (!(option_mask32 & FLAG_PATHLEN) || i <= TT.prefix) {
					// 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;
							xmkpath(name, -1);
							*s = '/';
						}
						TT.filein = xopen(name, O_CREAT|O_EXCL|O_RDWR);
					} else {
						printf("patching file %s\n", name);
						TT.filein = xopen(name, O_RDWR);
					}
					TT.fileout = copy_tempfile(TT.filein, name, &TT.tempname);
					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) {
		close(TT.filepatch);
		free(oldname);
		free(newname);
	}

	return TT.exitval;
}
