/*
 * 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/errors.h"
#include "common.h"
#include "diff.h"
#include "diff_driver.h"
#include "diff_patch.h"
#include "diff_xdiff.h"

static int git_xdiff_scan_int(const char **str, int *value)
{
	const char *scan = *str;
	int v = 0, digits = 0;
	/* find next digit */
	for (scan = *str; *scan && !git__isdigit(*scan); scan++);
	/* parse next number */
	for (; git__isdigit(*scan); scan++, digits++)
		v = (v * 10) + (*scan - '0');
	*str = scan;
	*value = v;
	return (digits > 0) ? 0 : -1;
}

static int git_xdiff_parse_hunk(git_diff_hunk *hunk, const char *header)
{
	/* expect something of the form "@@ -%d[,%d] +%d[,%d] @@" */
	if (*header != '@')
		goto fail;
	if (git_xdiff_scan_int(&header, &hunk->old_start) < 0)
		goto fail;
	if (*header == ',') {
		if (git_xdiff_scan_int(&header, &hunk->old_lines) < 0)
			goto fail;
	} else
		hunk->old_lines = 1;
	if (git_xdiff_scan_int(&header, &hunk->new_start) < 0)
		goto fail;
	if (*header == ',') {
		if (git_xdiff_scan_int(&header, &hunk->new_lines) < 0)
			goto fail;
	} else
		hunk->new_lines = 1;
	if (hunk->old_start < 0 || hunk->new_start < 0)
		goto fail;

	return 0;

fail:
	giterr_set(GITERR_INVALID, "Malformed hunk header from xdiff");
	return -1;
}

typedef struct {
	git_xdiff_output *xo;
	git_patch *patch;
	git_diff_hunk hunk;
	int old_lineno, new_lineno;
	mmfile_t xd_old_data, xd_new_data;
} git_xdiff_info;

static int diff_update_lines(
	git_xdiff_info *info,
	git_diff_line *line,
	const char *content,
	size_t content_len)
{
	const char *scan = content, *scan_end = content + content_len;

	for (line->num_lines = 0; scan < scan_end; ++scan)
		if (*scan == '\n')
			++line->num_lines;

	line->content     = content;
	line->content_len = content_len;

	/* expect " "/"-"/"+", then data */
	switch (line->origin) {
	case GIT_DIFF_LINE_ADDITION:
	case GIT_DIFF_LINE_DEL_EOFNL:
		line->old_lineno = -1;
		line->new_lineno = info->new_lineno;
		info->new_lineno += (int)line->num_lines;
		break;
	case GIT_DIFF_LINE_DELETION:
	case GIT_DIFF_LINE_ADD_EOFNL:
		line->old_lineno = info->old_lineno;
		line->new_lineno = -1;
		info->old_lineno += (int)line->num_lines;
		break;
	case GIT_DIFF_LINE_CONTEXT:
	case GIT_DIFF_LINE_CONTEXT_EOFNL:
		line->old_lineno = info->old_lineno;
		line->new_lineno = info->new_lineno;
		info->old_lineno += (int)line->num_lines;
		info->new_lineno += (int)line->num_lines;
		break;
	default:
		giterr_set(GITERR_INVALID, "Unknown diff line origin %02x",
			(unsigned int)line->origin);
		return -1;
	}

	return 0;
}

static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
{
	git_xdiff_info *info = priv;
	git_patch *patch = info->patch;
	const git_diff_delta *delta = git_patch_get_delta(patch);
	git_diff_output *output = &info->xo->output;
	git_diff_line line;

	if (len == 1) {
		output->error = git_xdiff_parse_hunk(&info->hunk, bufs[0].ptr);
		if (output->error < 0)
			return output->error;

		info->hunk.header_len = bufs[0].size;
		if (info->hunk.header_len >= sizeof(info->hunk.header))
			info->hunk.header_len = sizeof(info->hunk.header) - 1;
		memcpy(info->hunk.header, bufs[0].ptr, info->hunk.header_len);
		info->hunk.header[info->hunk.header_len] = '\0';

		if (output->hunk_cb != NULL &&
			(output->error = output->hunk_cb(
				delta, &info->hunk, output->payload)))
			return output->error;

		info->old_lineno = info->hunk.old_start;
		info->new_lineno = info->hunk.new_start;
	}

	if (len == 2 || len == 3) {
		/* expect " "/"-"/"+", then data */
		line.origin =
			(*bufs[0].ptr == '+') ? GIT_DIFF_LINE_ADDITION :
			(*bufs[0].ptr == '-') ? GIT_DIFF_LINE_DELETION :
			GIT_DIFF_LINE_CONTEXT;

		if (line.origin == GIT_DIFF_LINE_ADDITION)
			line.content_offset = bufs[1].ptr - info->xd_new_data.ptr;
		else if (line.origin == GIT_DIFF_LINE_DELETION)
			line.content_offset = bufs[1].ptr - info->xd_old_data.ptr;
		else
			line.content_offset = -1;

		output->error = diff_update_lines(
			info, &line, bufs[1].ptr, bufs[1].size);

		if (!output->error && output->data_cb != NULL)
			output->error = output->data_cb(
				delta, &info->hunk, &line, output->payload);
	}

	if (len == 3 && !output->error) {
		/* If we have a '+' and a third buf, then we have added a line
		 * without a newline and the old code had one, so DEL_EOFNL.
		 * If we have a '-' and a third buf, then we have removed a line
		 * with out a newline but added a blank line, so ADD_EOFNL.
		 */
		line.origin =
			(*bufs[0].ptr == '+') ? GIT_DIFF_LINE_DEL_EOFNL :
			(*bufs[0].ptr == '-') ? GIT_DIFF_LINE_ADD_EOFNL :
			GIT_DIFF_LINE_CONTEXT_EOFNL;

		line.content_offset = -1;

		output->error = diff_update_lines(
			info, &line, bufs[2].ptr, bufs[2].size);

		if (!output->error && output->data_cb != NULL)
			output->error = output->data_cb(
				delta, &info->hunk, &line, output->payload);
	}

	return output->error;
}

static int git_xdiff(git_diff_output *output, git_patch *patch)
{
	git_xdiff_output *xo = (git_xdiff_output *)output;
	git_xdiff_info info;
	git_diff_find_context_payload findctxt;

	memset(&info, 0, sizeof(info));
	info.patch = patch;
	info.xo    = xo;

	xo->callback.priv = &info;

	git_diff_find_context_init(
		&xo->config.find_func, &findctxt, git_patch__driver(patch));
	xo->config.find_func_priv = &findctxt;

	if (xo->config.find_func != NULL)
		xo->config.flags |= XDL_EMIT_FUNCNAMES;
	else
		xo->config.flags &= ~XDL_EMIT_FUNCNAMES;

	/* TODO: check ofile.opts_flags to see if driver-specific per-file
	 * updates are needed to xo->params.flags
	 */

	git_patch__old_data(&info.xd_old_data.ptr, &info.xd_old_data.size, patch);
	git_patch__new_data(&info.xd_new_data.ptr, &info.xd_new_data.size, patch);

	if (info.xd_old_data.size > GIT_XDIFF_MAX_SIZE ||
		info.xd_new_data.size > GIT_XDIFF_MAX_SIZE) {
		giterr_set(GITERR_INVALID, "files too large for diff");
		return -1;
	}

	xdl_diff(&info.xd_old_data, &info.xd_new_data,
		&xo->params, &xo->config, &xo->callback);

	git_diff_find_context_clear(&findctxt);

	return xo->output.error;
}

void git_xdiff_init(git_xdiff_output *xo, const git_diff_options *opts)
{
	uint32_t flags = opts ? opts->flags : 0;

	xo->output.diff_cb = git_xdiff;

	xo->config.ctxlen = opts ? opts->context_lines : 3;
	xo->config.interhunkctxlen = opts ? opts->interhunk_lines : 0;

	if (flags & GIT_DIFF_IGNORE_WHITESPACE)
		xo->params.flags |= XDF_WHITESPACE_FLAGS;
	if (flags & GIT_DIFF_IGNORE_WHITESPACE_CHANGE)
		xo->params.flags |= XDF_IGNORE_WHITESPACE_CHANGE;
	if (flags & GIT_DIFF_IGNORE_WHITESPACE_EOL)
		xo->params.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;

	if (flags & GIT_DIFF_PATIENCE)
		xo->params.flags |= XDF_PATIENCE_DIFF;
	if (flags & GIT_DIFF_MINIMAL)
		xo->params.flags |= XDF_NEED_MINIMAL;

	xo->callback.outf = git_xdiff_cb;
}
