/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */
#include "git2/patch.h"
#include "patch.h"
#include "patch_parse.h"
#include "diff_parse.h"
#include "path.h"

#define parse_err(...) \
	( giterr_set(GITERR_PATCH, __VA_ARGS__), -1 )

typedef struct {
	git_patch base;

	git_patch_parse_ctx *ctx;

	/* the paths from the `diff --git` header, these will be used if this is not
	 * a rename (and rename paths are specified) or if no `+++`/`---` line specify
	 * the paths.
	 */
	char *header_old_path, *header_new_path;

	/* renamed paths are precise and are not prefixed */
	char *rename_old_path, *rename_new_path;

	/* the paths given in `---` and `+++` lines */
	char *old_path, *new_path;

	/* the prefixes from the old/new paths */
	char *old_prefix, *new_prefix;
} git_patch_parsed;


GIT_INLINE(bool) parse_ctx_contains(
	git_patch_parse_ctx *ctx, const char *str, size_t len)
{
	return (ctx->line_len >= len && memcmp(ctx->line, str, len) == 0);
}

#define parse_ctx_contains_s(ctx, str) \
	parse_ctx_contains(ctx, str, sizeof(str) - 1)

static void parse_advance_line(git_patch_parse_ctx *ctx)
{
	ctx->line += ctx->line_len;
	ctx->remain_len -= ctx->line_len;
	ctx->line_len = git__linenlen(ctx->line, ctx->remain_len);
	ctx->line_num++;
}

static void parse_advance_chars(git_patch_parse_ctx *ctx, size_t char_cnt)
{
	ctx->line += char_cnt;
	ctx->remain_len -= char_cnt;
	ctx->line_len -= char_cnt;
}

static int parse_advance_expected(
	git_patch_parse_ctx *ctx,
	const char *expected,
	size_t expected_len)
{
	if (ctx->line_len < expected_len)
		return -1;

	if (memcmp(ctx->line, expected, expected_len) != 0)
		return -1;

	parse_advance_chars(ctx, expected_len);
	return 0;
}

#define parse_advance_expected_str(ctx, str) \
	parse_advance_expected(ctx, str, strlen(str))

static int parse_advance_ws(git_patch_parse_ctx *ctx)
{
	int ret = -1;

	while (ctx->line_len > 0 &&
		ctx->line[0] != '\n' &&
		git__isspace(ctx->line[0])) {
		ctx->line++;
		ctx->line_len--;
		ctx->remain_len--;
		ret = 0;
	}

	return ret;
}

static int parse_advance_nl(git_patch_parse_ctx *ctx)
{
	if (ctx->line_len != 1 || ctx->line[0] != '\n')
		return -1;

	parse_advance_line(ctx);
	return 0;
}

static int header_path_len(git_patch_parse_ctx *ctx)
{
	bool inquote = 0;
	bool quoted = (ctx->line_len > 0 && ctx->line[0] == '"');
	size_t len;

	for (len = quoted; len < ctx->line_len; len++) {
		if (!quoted && git__isspace(ctx->line[len]))
			break;
		else if (quoted && !inquote && ctx->line[len] == '"') {
			len++;
			break;
		}

		inquote = (!inquote && ctx->line[len] == '\\');
	}

	return len;
}

static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx)
{
	int path_len, error = 0;

	path_len = header_path_len(ctx);

	if ((error = git_buf_put(path, ctx->line, path_len)) < 0)
		goto done;

	parse_advance_chars(ctx, path_len);

	git_buf_rtrim(path);

	if (path->size > 0 && path->ptr[0] == '"')
		error = git_buf_unquote(path);

	if (error < 0)
		goto done;

	git_path_squash_slashes(path);

done:
	return error;
}

static int parse_header_path(char **out, git_patch_parse_ctx *ctx)
{
	git_buf path = GIT_BUF_INIT;
	int error = parse_header_path_buf(&path, ctx);

	*out = git_buf_detach(&path);

	return error;
}

static int parse_header_git_oldpath(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	return parse_header_path(&patch->old_path, ctx);
}

static int parse_header_git_newpath(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	return parse_header_path(&patch->new_path, ctx);
}

static int parse_header_mode(uint16_t *mode, git_patch_parse_ctx *ctx)
{
	const char *end;
	int32_t m;
	int ret;

	if (ctx->line_len < 1 || !git__isdigit(ctx->line[0]))
		return parse_err("invalid file mode at line %"PRIuZ, ctx->line_num);

	if ((ret = git__strntol32(&m, ctx->line, ctx->line_len, &end, 8)) < 0)
		return ret;

	if (m > UINT16_MAX)
		return -1;

	*mode = (uint16_t)m;

	parse_advance_chars(ctx, (end - ctx->line));

	return ret;
}

static int parse_header_oid(
	git_oid *oid,
	uint16_t *oid_len,
	git_patch_parse_ctx *ctx)
{
	size_t len;

	for (len = 0; len < ctx->line_len && len < GIT_OID_HEXSZ; len++) {
		if (!git__isxdigit(ctx->line[len]))
			break;
	}

	if (len < GIT_OID_MINPREFIXLEN || len > GIT_OID_HEXSZ ||
		git_oid_fromstrn(oid, ctx->line, len) < 0)
		return parse_err("invalid hex formatted object id at line %"PRIuZ,
			ctx->line_num);

	parse_advance_chars(ctx, len);

	*oid_len = (uint16_t)len;

	return 0;
}

static int parse_header_git_index(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	if (parse_header_oid(&patch->base.delta->old_file.id,
			&patch->base.delta->old_file.id_abbrev, ctx) < 0 ||
		parse_advance_expected_str(ctx, "..") < 0 ||
		parse_header_oid(&patch->base.delta->new_file.id,
			&patch->base.delta->new_file.id_abbrev, ctx) < 0)
		return -1;

	if (ctx->line_len > 0 && ctx->line[0] == ' ') {
		uint16_t mode;

		parse_advance_chars(ctx, 1);

		if (parse_header_mode(&mode, ctx) < 0)
			return -1;

		if (!patch->base.delta->new_file.mode)
			patch->base.delta->new_file.mode = mode;

		if (!patch->base.delta->old_file.mode)
			patch->base.delta->old_file.mode = mode;
	}

	return 0;
}

static int parse_header_git_oldmode(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	return parse_header_mode(&patch->base.delta->old_file.mode, ctx);
}

static int parse_header_git_newmode(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	return parse_header_mode(&patch->base.delta->new_file.mode, ctx);
}

static int parse_header_git_deletedfilemode(
	git_patch_parsed *patch,
	git_patch_parse_ctx *ctx)
{
	git__free((char *)patch->base.delta->old_file.path);

	patch->base.delta->old_file.path = NULL;
	patch->base.delta->status = GIT_DELTA_DELETED;
	patch->base.delta->nfiles = 1;

	return parse_header_mode(&patch->base.delta->old_file.mode, ctx);
}

static int parse_header_git_newfilemode(
	git_patch_parsed *patch,
	git_patch_parse_ctx *ctx)
{
	git__free((char *)patch->base.delta->new_file.path);

	patch->base.delta->new_file.path = NULL;
	patch->base.delta->status = GIT_DELTA_ADDED;
	patch->base.delta->nfiles = 1;

	return parse_header_mode(&patch->base.delta->new_file.mode, ctx);
}

static int parse_header_rename(
	char **out,
	git_patch_parse_ctx *ctx)
{
	git_buf path = GIT_BUF_INIT;

	if (parse_header_path_buf(&path, ctx) < 0)
		return -1;

	/* Note: the `rename from` and `rename to` lines include the literal
	 * filename.  They do *not* include the prefix.  (Who needs consistency?)
	 */
	*out = git_buf_detach(&path);
	return 0;
}

static int parse_header_renamefrom(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	patch->base.delta->status = GIT_DELTA_RENAMED;
	return parse_header_rename(&patch->rename_old_path, ctx);
}

static int parse_header_renameto(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	patch->base.delta->status = GIT_DELTA_RENAMED;
	return parse_header_rename(&patch->rename_new_path, ctx);
}

static int parse_header_copyfrom(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	patch->base.delta->status = GIT_DELTA_COPIED;
	return parse_header_rename(&patch->rename_old_path, ctx);
}

static int parse_header_copyto(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	patch->base.delta->status = GIT_DELTA_COPIED;
	return parse_header_rename(&patch->rename_new_path, ctx);
}

static int parse_header_percent(uint16_t *out, git_patch_parse_ctx *ctx)
{
	int32_t val;
	const char *end;

	if (ctx->line_len < 1 || !git__isdigit(ctx->line[0]) ||
		git__strntol32(&val, ctx->line, ctx->line_len, &end, 10) < 0)
		return -1;

	parse_advance_chars(ctx, (end - ctx->line));

	if (parse_advance_expected_str(ctx, "%") < 0)
		return -1;

	if (val > 100)
		return -1;

	*out = val;
	return 0;
}

static int parse_header_similarity(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	if (parse_header_percent(&patch->base.delta->similarity, ctx) < 0)
		return parse_err("invalid similarity percentage at line %"PRIuZ,
			ctx->line_num);

	return 0;
}

static int parse_header_dissimilarity(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	uint16_t dissimilarity;

	if (parse_header_percent(&dissimilarity, ctx) < 0)
		return parse_err("invalid similarity percentage at line %"PRIuZ,
			ctx->line_num);

	patch->base.delta->similarity = 100 - dissimilarity;

	return 0;
}

typedef struct {
	const char *str;
	int(*fn)(git_patch_parsed *, git_patch_parse_ctx *);
} header_git_op;

static const header_git_op header_git_ops[] = {
	{ "diff --git ", NULL },
	{ "@@ -", NULL },
	{ "GIT binary patch", NULL },
	{ "Binary files ", NULL },
	{ "--- ", parse_header_git_oldpath },
	{ "+++ ", parse_header_git_newpath },
	{ "index ", parse_header_git_index },
	{ "old mode ", parse_header_git_oldmode },
	{ "new mode ", parse_header_git_newmode },
	{ "deleted file mode ", parse_header_git_deletedfilemode },
	{ "new file mode ", parse_header_git_newfilemode },
	{ "rename from ", parse_header_renamefrom },
	{ "rename to ", parse_header_renameto },
	{ "rename old ", parse_header_renamefrom },
	{ "rename new ", parse_header_renameto },
	{ "copy from ", parse_header_copyfrom },
	{ "copy to ", parse_header_copyto },
	{ "similarity index ", parse_header_similarity },
	{ "dissimilarity index ", parse_header_dissimilarity },
};

static int parse_header_git(
	git_patch_parsed *patch,
	git_patch_parse_ctx *ctx)
{
	size_t i;
	int error = 0;

	/* Parse the diff --git line */
	if (parse_advance_expected_str(ctx, "diff --git ") < 0)
		return parse_err("corrupt git diff header at line %"PRIuZ, ctx->line_num);

	if (parse_header_path(&patch->header_old_path, ctx) < 0)
		return parse_err("corrupt old path in git diff header at line %"PRIuZ,
			ctx->line_num);

	if (parse_advance_ws(ctx) < 0 ||
		parse_header_path(&patch->header_new_path, ctx) < 0)
		return parse_err("corrupt new path in git diff header at line %"PRIuZ,
			ctx->line_num);

	/* Parse remaining header lines */
	for (parse_advance_line(ctx);
		ctx->remain_len > 0;
		parse_advance_line(ctx)) {

		bool found = false;

		if (ctx->line_len == 0 || ctx->line[ctx->line_len - 1] != '\n')
			break;

		for (i = 0; i < ARRAY_SIZE(header_git_ops); i++) {
			const header_git_op *op = &header_git_ops[i];
			size_t op_len = strlen(op->str);

			if (memcmp(ctx->line, op->str, min(op_len, ctx->line_len)) != 0)
				continue;

			/* Do not advance if this is the patch separator */
			if (op->fn == NULL)
				goto done;

			parse_advance_chars(ctx, op_len);

			if ((error = op->fn(patch, ctx)) < 0)
				goto done;

			parse_advance_ws(ctx);
			parse_advance_expected_str(ctx, "\n");

			if (ctx->line_len > 0) {
				error = parse_err("trailing data at line %"PRIuZ, ctx->line_num);
				goto done;
			}

			found = true;
			break;
		}
		
		if (!found) {
			error = parse_err("invalid patch header at line %"PRIuZ,
				ctx->line_num);
			goto done;
		}
	}

done:
	return error;
}

static int parse_number(git_off_t *out, git_patch_parse_ctx *ctx)
{
	const char *end;
	int64_t num;

	if (!git__isdigit(ctx->line[0]))
		return -1;

	if (git__strntol64(&num, ctx->line, ctx->line_len, &end, 10) < 0)
		return -1;

	if (num < 0)
		return -1;

	*out = num;
	parse_advance_chars(ctx, (end - ctx->line));

	return 0;
}

static int parse_int(int *out, git_patch_parse_ctx *ctx)
{
	git_off_t num;

	if (parse_number(&num, ctx) < 0 || !git__is_int(num))
		return -1;

	*out = (int)num;
	return 0;
}

static int parse_hunk_header(
	git_patch_hunk *hunk,
	git_patch_parse_ctx *ctx)
{
	const char *header_start = ctx->line;

	hunk->hunk.old_lines = 1;
	hunk->hunk.new_lines = 1;

	if (parse_advance_expected_str(ctx, "@@ -") < 0 ||
		parse_int(&hunk->hunk.old_start, ctx) < 0)
		goto fail;

	if (ctx->line_len > 0 && ctx->line[0] == ',') {
		if (parse_advance_expected_str(ctx, ",") < 0 ||
			parse_int(&hunk->hunk.old_lines, ctx) < 0)
			goto fail;
	}

	if (parse_advance_expected_str(ctx, " +") < 0 ||
		parse_int(&hunk->hunk.new_start, ctx) < 0)
		goto fail;

	if (ctx->line_len > 0 && ctx->line[0] == ',') {
		if (parse_advance_expected_str(ctx, ",") < 0 ||
			parse_int(&hunk->hunk.new_lines, ctx) < 0)
			goto fail;
	}

	if (parse_advance_expected_str(ctx, " @@") < 0)
		goto fail;

	parse_advance_line(ctx);

	if (!hunk->hunk.old_lines && !hunk->hunk.new_lines)
		goto fail;

	hunk->hunk.header_len = ctx->line - header_start;
	if (hunk->hunk.header_len > (GIT_DIFF_HUNK_HEADER_SIZE - 1))
		return parse_err("oversized patch hunk header at line %"PRIuZ,
			ctx->line_num);

	memcpy(hunk->hunk.header, header_start, hunk->hunk.header_len);
	hunk->hunk.header[hunk->hunk.header_len] = '\0';

	return 0;

fail:
	giterr_set(GITERR_PATCH, "invalid patch hunk header at line %"PRIuZ,
		ctx->line_num);
	return -1;
}

static int parse_hunk_body(
	git_patch_parsed *patch,
	git_patch_hunk *hunk,
	git_patch_parse_ctx *ctx)
{
	git_diff_line *line;
	int error = 0;

	int oldlines = hunk->hunk.old_lines;
	int newlines = hunk->hunk.new_lines;

	for (;
		ctx->remain_len > 4 && (oldlines || newlines) &&
		memcmp(ctx->line, "@@ -", 4) != 0;
		parse_advance_line(ctx)) {

		int origin;
		int prefix = 1;

		if (ctx->line_len == 0 || ctx->line[ctx->line_len - 1] != '\n') {
			error = parse_err("invalid patch instruction at line %"PRIuZ,
				ctx->line_num);
			goto done;
		}

		switch (ctx->line[0]) {
		case '\n':
			prefix = 0;

		case ' ':
			origin = GIT_DIFF_LINE_CONTEXT;
			oldlines--;
			newlines--;
			break;

		case '-':
			origin = GIT_DIFF_LINE_DELETION;
			oldlines--;
			break;

		case '+':
			origin = GIT_DIFF_LINE_ADDITION;
			newlines--;
			break;

		default:
			error = parse_err("invalid patch hunk at line %"PRIuZ, ctx->line_num);
			goto done;
		}

		line = git_array_alloc(patch->base.lines);
		GITERR_CHECK_ALLOC(line);

		memset(line, 0x0, sizeof(git_diff_line));

		line->content = ctx->line + prefix;
		line->content_len = ctx->line_len - prefix;
		line->content_offset = ctx->content_len - ctx->remain_len;
		line->origin = origin;

		hunk->line_count++;
	}

	if (oldlines || newlines) {
		error = parse_err(
			"invalid patch hunk, expected %d old lines and %d new lines",
			hunk->hunk.old_lines, hunk->hunk.new_lines);
		goto done;
	}

	/* Handle "\ No newline at end of file".  Only expect the leading
	 * backslash, though, because the rest of the string could be
	 * localized.  Because `diff` optimizes for the case where you
	 * want to apply the patch by hand.
	 */
	if (parse_ctx_contains_s(ctx, "\\ ") &&
		git_array_size(patch->base.lines) > 0) {

		line = git_array_get(patch->base.lines, git_array_size(patch->base.lines) - 1);

		if (line->content_len < 1) {
			error = parse_err("cannot trim trailing newline of empty line");
			goto done;
		}

		line->content_len--;

		parse_advance_line(ctx);
	}

done:
	return error;
}

static int parse_patch_header(
	git_patch_parsed *patch,
	git_patch_parse_ctx *ctx)
{
	int error = 0;

	for (ctx->line = ctx->remain;
		ctx->remain_len > 0;
		parse_advance_line(ctx)) {

		/* This line is too short to be a patch header. */
		if (ctx->line_len < 6)
			continue;

		/* This might be a hunk header without a patch header, provide a
		 * sensible error message. */
		if (parse_ctx_contains_s(ctx, "@@ -")) {
			size_t line_num = ctx->line_num;
			git_patch_hunk hunk;

			/* If this cannot be parsed as a hunk header, it's just leading
			* noise, continue.
			*/
			if (parse_hunk_header(&hunk, ctx) < 0) {
				giterr_clear();
				continue;
			}

			error = parse_err("invalid hunk header outside patch at line %"PRIuZ,
				line_num);
			goto done;
		}

		/* This buffer is too short to contain a patch. */
		if (ctx->remain_len < ctx->line_len + 6)
			break;

		/* A proper git patch */
		if (parse_ctx_contains_s(ctx, "diff --git ")) {
			error = parse_header_git(patch, ctx);
			goto done;
		}

		error = 0;
		continue;
	}

	giterr_set(GITERR_PATCH, "no patch found");
	error = GIT_ENOTFOUND;

done:
	return error;
}

static int parse_patch_binary_side(
	git_diff_binary_file *binary,
	git_patch_parse_ctx *ctx)
{
	git_diff_binary_t type = GIT_DIFF_BINARY_NONE;
	git_buf base85 = GIT_BUF_INIT, decoded = GIT_BUF_INIT;
	git_off_t len;
	int error = 0;

	if (parse_ctx_contains_s(ctx, "literal ")) {
		type = GIT_DIFF_BINARY_LITERAL;
		parse_advance_chars(ctx, 8);
	} else if (parse_ctx_contains_s(ctx, "delta ")) {
		type = GIT_DIFF_BINARY_DELTA;
		parse_advance_chars(ctx, 6);
	} else {
		error = parse_err(
			"unknown binary delta type at line %"PRIuZ, ctx->line_num);
		goto done;
	}

	if (parse_number(&len, ctx) < 0 || parse_advance_nl(ctx) < 0 || len < 0) {
		error = parse_err("invalid binary size at line %"PRIuZ, ctx->line_num);
		goto done;
	}

	while (ctx->line_len) {
		char c = ctx->line[0];
		size_t encoded_len, decoded_len = 0, decoded_orig = decoded.size;

		if (c == '\n')
			break;
		else if (c >= 'A' && c <= 'Z')
			decoded_len = c - 'A' + 1;
		else if (c >= 'a' && c <= 'z')
			decoded_len = c - 'a' + (('z' - 'a') + 1) + 1;

		if (!decoded_len) {
			error = parse_err("invalid binary length at line %"PRIuZ, ctx->line_num);
			goto done;
		}

		parse_advance_chars(ctx, 1);

		encoded_len = ((decoded_len / 4) + !!(decoded_len % 4)) * 5;

		if (encoded_len > ctx->line_len - 1) {
			error = parse_err("truncated binary data at line %"PRIuZ, ctx->line_num);
			goto done;
		}

		if ((error = git_buf_decode_base85(
			&decoded, ctx->line, encoded_len, decoded_len)) < 0)
			goto done;

		if (decoded.size - decoded_orig != decoded_len) {
			error = parse_err("truncated binary data at line %"PRIuZ, ctx->line_num);
			goto done;
		}

		parse_advance_chars(ctx, encoded_len);

		if (parse_advance_nl(ctx) < 0) {
			error = parse_err("trailing data at line %"PRIuZ, ctx->line_num);
			goto done;
		}
	}

	binary->type = type;
	binary->inflatedlen = (size_t)len;
	binary->datalen = decoded.size;
	binary->data = git_buf_detach(&decoded);

done:
	git_buf_free(&base85);
	git_buf_free(&decoded);
	return error;
}

static int parse_patch_binary(
	git_patch_parsed *patch,
	git_patch_parse_ctx *ctx)
{
	int error;

	if (parse_advance_expected_str(ctx, "GIT binary patch") < 0 ||
		parse_advance_nl(ctx) < 0)
		return parse_err("corrupt git binary header at line %"PRIuZ, ctx->line_num);

	/* parse old->new binary diff */
	if ((error = parse_patch_binary_side(
			&patch->base.binary.new_file, ctx)) < 0)
		return error;

	if (parse_advance_nl(ctx) < 0)
		return parse_err("corrupt git binary separator at line %"PRIuZ,
			ctx->line_num);

	/* parse new->old binary diff */
	if ((error = parse_patch_binary_side(
			&patch->base.binary.old_file, ctx)) < 0)
		return error;

	if (parse_advance_nl(ctx) < 0)
		return parse_err("corrupt git binary patch separator at line %"PRIuZ,
			ctx->line_num);

	patch->base.binary.contains_data = 1;
	patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY;
	return 0;
}

static int parse_patch_binary_nodata(
	git_patch_parsed *patch,
	git_patch_parse_ctx *ctx)
{
	if (parse_advance_expected_str(ctx, "Binary files ") < 0 ||
		parse_advance_expected_str(ctx, patch->header_old_path) < 0 ||
		parse_advance_expected_str(ctx, " and ") < 0 ||
		parse_advance_expected_str(ctx, patch->header_new_path) < 0 ||
		parse_advance_expected_str(ctx, " differ") < 0 ||
		parse_advance_nl(ctx) < 0)
		return parse_err("corrupt git binary header at line %"PRIuZ, ctx->line_num);

	patch->base.binary.contains_data = 0;
	patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY;
	return 0;
}

static int parse_patch_hunks(
	git_patch_parsed *patch,
	git_patch_parse_ctx *ctx)
{
	git_patch_hunk *hunk;
	int error = 0;

	while (parse_ctx_contains_s(ctx, "@@ -")) {
		hunk = git_array_alloc(patch->base.hunks);
		GITERR_CHECK_ALLOC(hunk);

		memset(hunk, 0, sizeof(git_patch_hunk));

		hunk->line_start = git_array_size(patch->base.lines);
		hunk->line_count = 0;

		if ((error = parse_hunk_header(hunk, ctx)) < 0 ||
			(error = parse_hunk_body(patch, hunk, ctx)) < 0)
			goto done;
	}

	patch->base.delta->flags |= GIT_DIFF_FLAG_NOT_BINARY;

done:
	return error;
}

static int parse_patch_body(
	git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	if (parse_ctx_contains_s(ctx, "GIT binary patch"))
		return parse_patch_binary(patch, ctx);
	else if (parse_ctx_contains_s(ctx, "Binary files "))
		return parse_patch_binary_nodata(patch, ctx);
	else
		return parse_patch_hunks(patch, ctx);
}

int check_header_names(
	const char *one,
	const char *two,
	const char *old_or_new,
	bool two_null)
{
	if (!one || !two)
		return 0;

	if (two_null && strcmp(two, "/dev/null") != 0)
		return parse_err("expected %s path of '/dev/null'", old_or_new);

	else if (!two_null && strcmp(one, two) != 0)
		return parse_err("mismatched %s path names", old_or_new);

	return 0;
}

static int check_prefix(
	char **out,
	size_t *out_len,
	git_patch_parsed *patch,
	const char *path_start)
{
	const char *path = path_start;
	size_t prefix_len = patch->ctx->opts.prefix_len;
	size_t remain_len = prefix_len;

	*out = NULL;
	*out_len = 0;

	if (prefix_len == 0)
		goto done;

	/* leading slashes do not count as part of the prefix in git apply */
	while (*path == '/')
		path++;

	while (*path && remain_len) {
		if (*path == '/')
			remain_len--;

		path++;
	}

	if (remain_len || !*path)
		return parse_err(
			"header filename does not contain %"PRIuZ" path components",
			prefix_len);

done:
	*out_len = (path - path_start);
	*out = git__strndup(path_start, *out_len);

	return (*out == NULL) ? -1 : 0;
}

static int check_filenames(git_patch_parsed *patch)
{
	const char *prefixed_new, *prefixed_old;
	size_t old_prefixlen = 0, new_prefixlen = 0;
	bool added = (patch->base.delta->status == GIT_DELTA_ADDED);
	bool deleted = (patch->base.delta->status == GIT_DELTA_DELETED);

	if (patch->old_path && !patch->new_path)
		return parse_err("missing new path");

	if (!patch->old_path && patch->new_path)
		return parse_err("missing old path");

	/* Ensure (non-renamed) paths match */
	if (check_header_names(
			patch->header_old_path, patch->old_path, "old", added) < 0 ||
		check_header_names(
			patch->header_new_path, patch->new_path, "new", deleted) < 0)
		return -1;

	prefixed_old = (!added && patch->old_path) ? patch->old_path :
		patch->header_old_path;
	prefixed_new = (!deleted && patch->new_path) ? patch->new_path :
		patch->header_new_path;

	if (check_prefix(
			&patch->old_prefix, &old_prefixlen, patch, prefixed_old) < 0 ||
		check_prefix(
			&patch->new_prefix, &new_prefixlen, patch, prefixed_new) < 0)
		return -1;

	/* Prefer the rename filenames as they are unambiguous and unprefixed */
	if (patch->rename_old_path)
		patch->base.delta->old_file.path = patch->rename_old_path;
	else
		patch->base.delta->old_file.path = prefixed_old + old_prefixlen;

	if (patch->rename_new_path)
		patch->base.delta->new_file.path = patch->rename_new_path;
	else
		patch->base.delta->new_file.path = prefixed_new + new_prefixlen;

	if (!patch->base.delta->old_file.path &&
		!patch->base.delta->new_file.path)
		return parse_err("git diff header lacks old / new paths");

	return 0;
}

static int check_patch(git_patch_parsed *patch)
{
	git_diff_delta *delta = patch->base.delta;

	if (check_filenames(patch) < 0)
		return -1;

	if (delta->old_file.path &&
			delta->status != GIT_DELTA_DELETED &&
			!delta->new_file.mode)
		delta->new_file.mode = delta->old_file.mode;

	if (delta->status == GIT_DELTA_MODIFIED &&
			!(delta->flags & GIT_DIFF_FLAG_BINARY) &&
			delta->new_file.mode == delta->old_file.mode &&
			git_array_size(patch->base.hunks) == 0)
		return parse_err("patch with no hunks");

	if (delta->status == GIT_DELTA_ADDED) {
		memset(&delta->old_file.id, 0x0, sizeof(git_oid));
		delta->old_file.id_abbrev = 0;
	}

	if (delta->status == GIT_DELTA_DELETED) {
		memset(&delta->new_file.id, 0x0, sizeof(git_oid));
		delta->new_file.id_abbrev = 0;
	}

	return 0;
}

git_patch_parse_ctx *git_patch_parse_ctx_init(
	const char *content,
	size_t content_len,
	const git_patch_options *opts)
{
	git_patch_parse_ctx *ctx;
	git_patch_options default_opts = GIT_PATCH_OPTIONS_INIT;

	if ((ctx = git__calloc(1, sizeof(git_patch_parse_ctx))) == NULL)
		return NULL;

	if (content_len) {
		if ((ctx->content = git__malloc(content_len)) == NULL) {
			git__free(ctx);
			return NULL;
		}

		memcpy((char *)ctx->content, content, content_len);
	}

	ctx->content_len = content_len;
	ctx->remain = ctx->content;
	ctx->remain_len = ctx->content_len;

	if (opts)
		memcpy(&ctx->opts, opts, sizeof(git_patch_options));
	else
		memcpy(&ctx->opts, &default_opts, sizeof(git_patch_options));

	GIT_REFCOUNT_INC(ctx);
	return ctx;
}

static void patch_parse_ctx_free(git_patch_parse_ctx *ctx)
{
	if (!ctx)
		return;

	git__free((char *)ctx->content);
	git__free(ctx);
}

void git_patch_parse_ctx_free(git_patch_parse_ctx *ctx)
{
	GIT_REFCOUNT_DEC(ctx, patch_parse_ctx_free);
}

int git_patch_parsed_from_diff(git_patch **out, git_diff *d, size_t idx)
{
	git_diff_parsed *diff = (git_diff_parsed *)d;
	git_patch *p;

	if ((p = git_vector_get(&diff->patches, idx)) == NULL)
		return -1;

	GIT_REFCOUNT_INC(p);
	*out = p;

	return 0;
}

static void patch_parsed__free(git_patch *p)
{
	git_patch_parsed *patch = (git_patch_parsed *)p;

	if (!patch)
		return;

	git_patch_parse_ctx_free(patch->ctx);

	git__free((char *)patch->base.binary.old_file.data);
	git__free((char *)patch->base.binary.new_file.data);
	git_array_clear(patch->base.hunks);
	git_array_clear(patch->base.lines);
	git__free(patch->base.delta);

	git__free(patch->old_prefix);
	git__free(patch->new_prefix);
	git__free(patch->header_old_path);
	git__free(patch->header_new_path);
	git__free(patch->rename_old_path);
	git__free(patch->rename_new_path);
	git__free(patch->old_path);
	git__free(patch->new_path);
	git__free(patch);
}

int git_patch_parse(
	git_patch **out,
	git_patch_parse_ctx *ctx)
{
	git_patch_parsed *patch;
	size_t start, used;
	int error = 0;

	assert(out && ctx);

	*out = NULL;

	patch = git__calloc(1, sizeof(git_patch_parsed));
	GITERR_CHECK_ALLOC(patch);

	patch->ctx = ctx;
	GIT_REFCOUNT_INC(patch->ctx);

	patch->base.free_fn = patch_parsed__free;

	patch->base.delta = git__calloc(1, sizeof(git_diff_delta));
	GITERR_CHECK_ALLOC(patch->base.delta);

	patch->base.delta->status = GIT_DELTA_MODIFIED;
	patch->base.delta->nfiles = 2;

	start = ctx->remain_len;

	if ((error = parse_patch_header(patch, ctx)) < 0 ||
		(error = parse_patch_body(patch, ctx)) < 0 ||
		(error = check_patch(patch)) < 0)
		goto done;

	used = start - ctx->remain_len;
	ctx->remain += used;

	patch->base.diff_opts.old_prefix = patch->old_prefix;
	patch->base.diff_opts.new_prefix = patch->new_prefix;
	patch->base.diff_opts.flags |= GIT_DIFF_SHOW_BINARY;

	GIT_REFCOUNT_INC(patch);
	*out = &patch->base;

done:
	if (error < 0)
		patch_parsed__free(&patch->base);

	return error;
}

int git_patch_from_buffer(
	git_patch **out,
	const char *content,
	size_t content_len,
	const git_patch_options *opts)
{
	git_patch_parse_ctx *ctx;
	int error;

	ctx = git_patch_parse_ctx_init(content, content_len, opts);
	GITERR_CHECK_ALLOC(ctx);

	error = git_patch_parse(out, ctx);

	git_patch_parse_ctx_free(ctx);
	return error;
}

