/* vi: set sw=4 ts=4: */
/*
 * patch.c - Apply a "universal" diff.
 *
 * SUSv3 at http://www.opengroup.org/onlinepubs/009695399/utilities/patch.html
 * but who cares about "ed"?
 *
 * -u ignored
 * -R reverse (remove applied hunks, apply removed hunks)
 * -p num remove this many slashes from start of path (default = all)
 *
 * 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
 * -i patchfile apply patch from filename rather than stdin
 * -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
 */

#include "toys.h"

#define TT toy.patch

#define FLAG_REVERSE 1
#define FLAG_PATHLEN 4

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

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


static void 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;
}

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

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

	printf("Hunk FAILED.\n");
	toys.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;
	llist_free(TT.plines, do_line);
	TT.plines = NULL;
	delete_tempfile(TT.filein, TT.fileout, &TT.tempname);
	TT.filein = -1;
}

static void apply_hunk(void)
{
	struct double_list *plist, *buf = NULL;
	int i = 0, backwards = 0, matcheof = 0,
		reverse = toys.optflags & FLAG_REVERSE;

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

	// Match EOF if there aren't as many ending context lines as beginning
	for (plist = TT.plines; plist; plist = plist->next) {
		if (plist->data[0]==' ') i++;
		else i = 0;
	}
	if (i < TT.context) matcheof++;

	// Search for a place to apply this hunk.  Match all context lines and
	// lines to be removed.
	plist = TT.plines;
	buf = NULL;
	i = 0;

	// Start of for loop
	if (TT.context) for (;;) {
		char *data = get_line(TT.filein);
		TT.linenum++;

		// Skip lines we'd add.
		while (plist && *plist->data == "+-"[reverse]) {
			if (data && !backwards && !strcmp(data, plist->data+1)) {
				backwards = 1;
				fdprintf(2,"Possibly reversed hunk at %ld\n", TT.linenum);
			}
			plist = plist->next;
		}

		if (!data) {
			// Matched EOF?
			if (!plist && matcheof) break;
			// File ended before we found a home for this hunk?
			fail_hunk();
			goto done;
		}
		dlist_add(&buf, data);

		if (!plist || strcmp(data, plist->data+1)) {     // Ignore whitespace?
			// Match failed, hunk doesn't go here.  Flush accumulated buffer
			// so far.

			buf->prev->next = NULL;
			TT.state = 1;
			llist_free(buf, do_line);
			buf = NULL;
			plist = TT.plines;
		} else {
			// Match, advance plist.
			plist = plist->next;
			if (!plist && !matcheof) break;
		}
	}

	// Got it.  Emit changed data.
	TT.state = "-+"[reverse];
	llist_free(TT.plines, do_line);
	TT.plines = NULL;
done:
	TT.state = 0;
	if (buf) {
		buf->prev->next = NULL;
		llist_free(buf, do_line);
	}
}

// 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

void patch_main(void)
{
	if (TT.infile) TT.filepatch = xopen(TT.infile, 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;

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

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

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

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

		// Open a new file?
		if (!strncmp("--- ", patchline, 4)) {
			char *s;
			free(TT.oldname);

			// 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++;
			*s = 0;

			TT.oldname = xstrdup(patchline+4);
		} else if (!strncmp("+++ ", patchline, 4)) {
			int i = 0, del = 0;
			char *s, *start;

			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++;
			*s = 0;


			// If new file is /dev/null (before -p), we're deleting oldname
			start = patchline+4;
			if (!strcmp(start, "/dev/null")) {
				start = TT.oldname;
				del++;
			} else start = patchline+4;
				
			// handle -p path truncation.
			for (s = start; *s;) {
				if ((toys.optflags & FLAG_PATHLEN) && TT.prefix == i) break;
				if (*(s++)=='/') {
					start = s;
					i++;
				}
			}

			if (del) xunlink(TT.oldname);
			// If we've got a file to open, do so.
			else if (!(toys.optflags & FLAG_PATHLEN) || i <= TT.prefix) {
				// If the old file was null, we're creating a new one.
				if (!strcmp(TT.oldname, "/dev/null")) {
					printf("creating %s\n", start);
					s = strrchr(start, '/');
					if (s) {
						*s = 0;
						xmkpath(start, -1);
						*s = '/';
					}
					TT.filein = xcreate(start, O_CREAT|O_RDWR, 0666);
				} else {
					printf("patching %s\n", start);
					TT.filein = xopen(start, O_RDWR);
				}
				TT.fileout = copy_tempfile(TT.filein, start, &TT.tempname);
				TT.state = 1;
				TT.context = 0;
				TT.linenum = 0;
			}

		// Start a new hunk?
		// Test filein rather than state to report only the first failed hunk.
		} else if (TT.filein!=-1 && !strncmp("@@ -", patchline, 4) &&
			4 == sscanf(patchline+4, "%ld,%ld +%ld,%ld", &TT.oldline,
				&TT.oldlen, &TT.newline, &TT.newlen))
		{
			TT.context = 0;
			TT.state = 2;
			continue;
		}

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

	finish_oldfile();

	if (CFG_TOYBOX_FREE) {
		close(TT.filepatch);
		free(TT.oldname);
	}
}
