/* vi:set ts=8 sts=4 sw=4 noet:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

#include "vim.h"

#define LN_MAX_BUFS 8
#define LN_DECISION_MAX 255  // pow(2, LN_MAX_BUFS(8)) - 1 = 255

// struct for running the diff linematch algorithm
typedef struct diffcmppath_S diffcmppath_T;
struct diffcmppath_S
{
    // to keep track of the total score of this path
    int			df_lev_score;
    size_t		df_path_n;	// current index of this path
    int			df_choice_mem[LN_DECISION_MAX + 1];
    int			df_choice[LN_DECISION_MAX];
    // to keep track of this path traveled
    diffcmppath_T	*df_decision[LN_DECISION_MAX];
    size_t		df_optimal_choice;
};

static int matching_chars(const mmfile_t *m1, const mmfile_t *m2);
static size_t unwrap_indexes(const int *values, const int *diff_len, const size_t ndiffs);
static size_t test_charmatch_paths(diffcmppath_T *node, int lastdecision);

    static size_t
line_len(const mmfile_t *m)
{
    char	*s = m->ptr;
    char	*end;

    end = memchr(s, '\n', (size_t)m->size);
    return end ? (size_t)(end - s) : (size_t)m->size;
}

#define MATCH_CHAR_MAX_LEN 800

/// Same as matching_chars but ignore whitespace
///
/// @param s1
/// @param s2
    static int
matching_chars_iwhite(const mmfile_t *s1, const mmfile_t *s2)
{
    // the newly processed strings that will be compared
    // delete the white space characters
    mmfile_t	sp[2];
    char	p[2][MATCH_CHAR_MAX_LEN];

    for (int k = 0; k < 2; k++)
    {
	const	mmfile_t *s = k == 0 ? s1 : s2;
	size_t	pi = 0;
	size_t	slen = MIN(MATCH_CHAR_MAX_LEN - 1, line_len(s));

	for (size_t i = 0; i <= slen; i++)
	{
	    char e = s->ptr[i];

	    if (e != ' ' && e != '\t')
	    {
		p[k][pi] = e;
		pi++;
	    }
	}

	sp[k].ptr = p[k];
	sp[k].size = (int)pi;
    }

    return matching_chars(&sp[0], &sp[1]);
}

/// Return matching characters between "s1" and "s2" whilst respecting sequence
/// order.
/// Consider the case of two strings 'AAACCC' and 'CCCAAA', the
/// return value from this function will be 3, either to match
/// the 3 C's, or the 3 A's.
///
/// Examples:
///   matching_chars("aabc", "acba")               -> 2  // 'a' and 'b' in common
///   matching_chars("123hello567", "he123ll567o") -> 8  // '123', 'll' and '567' in common
///   matching_chars("abcdefg", "gfedcba")         -> 1  // all characters in common,
///                                                      // but only at most 1 in sequence
///
/// @param m1
/// @param m2
    static int
matching_chars(const mmfile_t *m1, const mmfile_t *m2)
{
    size_t	s1len = MIN(MATCH_CHAR_MAX_LEN - 1, line_len(m1));
    size_t	s2len = MIN(MATCH_CHAR_MAX_LEN - 1, line_len(m2));
    char	*s1 = m1->ptr;
    char	*s2 = m2->ptr;
    int		matrix[2][MATCH_CHAR_MAX_LEN] = { 0 };
    int		icur = 1;  // save space by storing only two rows for i axis

    for (size_t i = 0; i < s1len; i++)
    {
	icur = (icur == 1 ? 0 : 1);
	int *e1 = matrix[icur];
	int *e2 = matrix[!icur];

	for (size_t j = 0; j < s2len; j++)
	{
	    // skip char in s1
	    if (e2[j + 1] > e1[j + 1])
		e1[j + 1] = e2[j + 1];
	    // skip char in s2
	    if (e1[j] > e1[j + 1])
		e1[j + 1] = e1[j];
	    // compare char in s1 and s2
	    if ((s1[i] == s2[j]) && (e2[j] + 1) > e1[j + 1])
		e1[j + 1] = e2[j] + 1;
	}
    }

    return matrix[icur][s2len];
}

/// count the matching characters between a variable number of strings "sp"
/// mark the strings that have already been compared to extract them later
/// without re-running the character match counting.
/// @param sp
/// @param fomvals
/// @param n
    static int
count_n_matched_chars(mmfile_t **sp, const size_t n, int iwhite)
{
    int matched_chars = 0;
    int matched = 0;

    for (size_t i = 0; i < n; i++)
    {
	for (size_t j = i + 1; j < n; j++)
	{
	    if (sp[i]->ptr != NULL && sp[j]->ptr != NULL)
	    {
		matched++;
		// TODO(lewis6991): handle whitespace ignoring higher up in the
		// stack
		matched_chars += iwhite ? matching_chars_iwhite(sp[i], sp[j])
					: matching_chars(sp[i], sp[j]);
	    }
	}
    }

    // prioritize a match of 3 (or more lines) equally to a match of 2 lines
    if (matched >= 2)
    {
	matched_chars *= 2;
	matched_chars /= matched;
    }

    return matched_chars;
}

    static mmfile_t
fastforward_buf_to_lnum(mmfile_t s, linenr_T lnum)
{
    for (int i = 0; i < lnum - 1; i++)
    {
	char *line_end;

	line_end = memchr(s.ptr, '\n', (size_t)s.size);
	s.size = line_end ? (int)(s.size - (line_end - s.ptr)) : 0;
	s.ptr = line_end;
	if (!s.ptr)
	    break;
	s.ptr++;
	s.size--;
    }

    return s;
}

/// try all the different ways to compare these lines and use the one that
/// results in the most matching characters
/// @param df_iters
/// @param paths
/// @param npaths
/// @param path_idx
/// @param choice
/// @param diffcmppath
/// @param diff_len
/// @param ndiffs
/// @param diff_blk
    static void
try_possible_paths(
    const int		*df_iters,
    const size_t	*paths,
    const int		npaths,
    const int		path_idx,
    int			*choice,
    diffcmppath_T	*diffcmppath,
    const int		*diff_len,
    const size_t	ndiffs,
    const mmfile_t	**diff_blk,
    int			iwhite)
{
    if (path_idx == npaths)
    {
	if ((*choice) > 0)
	{
	    int from_vals[LN_MAX_BUFS] = { 0 };
	    const int *to_vals = df_iters;

	    mmfile_t mm[LN_MAX_BUFS];  // stack memory for current_lines
	    mmfile_t *current_lines[LN_MAX_BUFS];
	    for (size_t k = 0; k < ndiffs; k++)
	    {
		from_vals[k] = df_iters[k];
		// get the index at all of the places
		if ((*choice) & (1 << k))
		{
		    from_vals[k]--;
		    mm[k] = fastforward_buf_to_lnum(*diff_blk[k], df_iters[k]);
		}
		else
		    CLEAR_FIELD(mm[k]);
		current_lines[k] = &mm[k];
	    }
	    size_t unwrapped_idx_from = unwrap_indexes(from_vals, diff_len, ndiffs);
	    size_t unwrapped_idx_to = unwrap_indexes(to_vals, diff_len, ndiffs);
	    int matched_chars = count_n_matched_chars(current_lines, ndiffs, iwhite);
	    int score = diffcmppath[unwrapped_idx_from].df_lev_score + matched_chars;

	    if (score > diffcmppath[unwrapped_idx_to].df_lev_score)
	    {
		diffcmppath[unwrapped_idx_to].df_path_n = 1;
		diffcmppath[unwrapped_idx_to].df_decision[0] =
					&diffcmppath[unwrapped_idx_from];
		diffcmppath[unwrapped_idx_to].df_choice[0] = *choice;
		diffcmppath[unwrapped_idx_to].df_lev_score = score;
	    }
	    else if (score == diffcmppath[unwrapped_idx_to].df_lev_score)
	    {
		size_t k = diffcmppath[unwrapped_idx_to].df_path_n++;
		diffcmppath[unwrapped_idx_to].df_decision[k] =
					&diffcmppath[unwrapped_idx_from];
		diffcmppath[unwrapped_idx_to].df_choice[k] = *choice;
	    }
	}
	return;
    }

    size_t bit_place = paths[path_idx];
    *(choice) |= (1 << bit_place);  // set it to 1
    try_possible_paths(df_iters, paths, npaths, path_idx + 1, choice,
	    diffcmppath, diff_len, ndiffs, diff_blk, iwhite);
    *(choice) &= ~(1 << bit_place);  // set it to 0
    try_possible_paths(df_iters, paths, npaths, path_idx + 1, choice,
	    diffcmppath, diff_len, ndiffs, diff_blk, iwhite);
}

/// unwrap indexes to access n dimensional tensor
/// @param values
/// @param diff_len
/// @param ndiffs
    static size_t
unwrap_indexes(const int *values, const int *diff_len, const size_t ndiffs)
{
    size_t num_unwrap_scalar = 1;

    for (size_t k = 0; k < ndiffs; k++)
	num_unwrap_scalar *= (size_t)diff_len[k] + 1;

    size_t path_idx = 0;
    for (size_t k = 0; k < ndiffs; k++)
    {
	num_unwrap_scalar /= (size_t)diff_len[k] + 1;

	int n = values[k];
	path_idx += num_unwrap_scalar * (size_t)n;
    }

    return path_idx;
}

/// populate the values of the linematch algorithm tensor, and find the best
/// decision for how to compare the relevant lines from each of the buffers at
/// each point in the tensor
/// @param df_iters
/// @param ch_dim
/// @param diffcmppath
/// @param diff_len
/// @param ndiffs
/// @param diff_blk
    static void
populate_tensor(
    int			*df_iters,
    const size_t	ch_dim,
    diffcmppath_T	*diffcmppath,
    const int		*diff_len,
    const size_t	ndiffs,
    const mmfile_t	**diff_blk,
    int			iwhite)
{
    if (ch_dim == ndiffs)
    {
	int npaths = 0;
	size_t paths[LN_MAX_BUFS];

	for (size_t j = 0; j < ndiffs; j++)
	{
	    if (df_iters[j] > 0)
	    {
		paths[npaths] = j;
		npaths++;
	    }
	}

	int choice = 0;
	size_t unwrapper_idx_to = unwrap_indexes(df_iters, diff_len, ndiffs);

	diffcmppath[unwrapper_idx_to].df_lev_score = -1;
	try_possible_paths(df_iters, paths, npaths, 0, &choice, diffcmppath,
					diff_len, ndiffs, diff_blk, iwhite);
	return;
    }

    for (int i = 0; i <= diff_len[ch_dim]; i++)
    {
	df_iters[ch_dim] = i;
	populate_tensor(df_iters, ch_dim + 1, diffcmppath, diff_len,
		ndiffs, diff_blk, iwhite);
    }
}

/// algorithm to find an optimal alignment of lines of a diff block with 2 or
/// more files. The algorithm is generalized to work for any number of files
/// which corresponds to another dimension added to the tensor used in the
/// algorithm
///
/// for questions and information about the linematch algorithm please contact
/// Jonathon White (jonathonwhite@protonmail.com)
///
/// for explanation, a summary of the algorithm in 3 dimensions (3 files
///     compared) follows
///
/// The 3d case (for 3 buffers) of the algorithm implemented when diffopt
/// 'linematch' is enabled. The algorithm constructs a 3d tensor to
/// compare a diff between 3 buffers. The dimensions of the tensor are
/// the length of the diff in each buffer plus 1 A path is constructed by
/// moving from one edge of the cube/3d tensor to the opposite edge.
/// Motions from one cell of the cube to the next represent decisions. In
/// a 3d cube, there are a total of 7 decisions that can be made,
/// represented by the enum df_path3_choice which is defined in
/// buffer_defs.h a comparison of buffer 0 and 1 represents a motion
/// toward the opposite edge of the cube with components along the 0 and
/// 1 axes.  a comparison of buffer 0, 1, and 2 represents a motion
/// toward the opposite edge of the cube with components along the 0, 1,
/// and 2 axes. A skip of buffer 0 represents a motion along only the 0
/// axis. For each action, a point value is awarded, and the path is
/// saved for reference later, if it is found to have been the optimal
/// path. The optimal path has the highest score.  The score is
/// calculated as the summation of the total characters matching between
/// all of the lines which were compared. The structure of the algorithm
/// is that of a dynamic programming problem.  We can calculate a point
/// i,j,k in the cube as a function of i-1, j-1, and k-1. To find the
/// score and path at point i,j,k, we must determine which path we want
/// to use, this is done by looking at the possibilities and choosing
/// the one which results in the local highest score.  The total highest
/// scored path is, then in the end represented by the cell in the
/// opposite corner from the start location.  The entire algorithm
/// consists of populating the 3d cube with the optimal paths from which
/// it may have came.
///
/// Optimizations:
/// As the function to calculate the cell of a tensor at point i,j,k is a
/// function of the cells at i-1, j-1, k-1, the whole tensor doesn't need
/// to be stored in memory at once. In the case of the 3d cube, only two
/// slices (along k and j axis) are stored in memory. For the 2d matrix
/// (for 2 files), only two rows are stored at a time. The next/previous
/// slice (or row) is always calculated from the other, and they alternate
/// at each iteration.
/// In the 3d case, 3 arrays are populated to memorize the score (matched
/// characters) of the 3 buffers, so a redundant calculation of the
/// scores does not occur
/// @param diff_blk
/// @param diff_len
/// @param ndiffs
/// @param [out] [allocated] decisions
/// @return the length of decisions
    size_t
linematch_nbuffers(
    const mmfile_t	**diff_blk,
    const int		*diff_len,
    const size_t	ndiffs,
    int			**decisions,
    int			iwhite)
{
    assert(ndiffs <= LN_MAX_BUFS);

    size_t memsize = 1;
    size_t memsize_decisions = 0;
    for (size_t i = 0; i < ndiffs; i++)
    {
	assert(diff_len[i] >= 0);
	memsize *= (size_t)(diff_len[i] + 1);
	memsize_decisions += (size_t)diff_len[i];
    }

    // create the flattened path matrix
    diffcmppath_T *diffcmppath = lalloc(sizeof(diffcmppath_T) * memsize, TRUE);
    if (diffcmppath == NULL)
	return 0;

    // allocate memory here
    size_t n = (size_t)pow(2.0, (double)ndiffs);
    for (size_t i = 0; i < memsize; i++)
    {
	diffcmppath[i].df_lev_score = 0;
	diffcmppath[i].df_path_n = 0;
	for (size_t j = 0; j < n; j++)
	    diffcmppath[i].df_choice_mem[j] = -1;
    }

    // memory for avoiding repetitive calculations of score
    int df_iters[LN_MAX_BUFS];
    populate_tensor(df_iters, 0, diffcmppath, diff_len, ndiffs, diff_blk,
		    iwhite);

    const size_t u = unwrap_indexes(diff_len, diff_len, ndiffs);
    diffcmppath_T *startNode = &diffcmppath[u];

    *decisions = lalloc(sizeof(int) * memsize_decisions, TRUE);
    if (*decisions == NULL)
    {
	vim_free(diffcmppath);
	return 0;
    }

    size_t n_optimal = 0;
    test_charmatch_paths(startNode, 0);
    while (startNode->df_path_n > 0)
    {
	size_t j = startNode->df_optimal_choice;
	(*decisions)[n_optimal++] = startNode->df_choice[j];
	startNode = startNode->df_decision[j];
    }
    // reverse array
    for (size_t i = 0; i < (n_optimal / 2); i++)
    {
	int tmp = (*decisions)[i];
	(*decisions)[i] = (*decisions)[n_optimal - 1 - i];
	(*decisions)[n_optimal - 1 - i] = tmp;
    }

    vim_free(diffcmppath);

    return n_optimal;
}

// returns the minimum amount of path changes from start to end
    static size_t
test_charmatch_paths(diffcmppath_T *node, int lastdecision)
{
    // memoization
    if (node->df_choice_mem[lastdecision] == -1)
    {
	if (node->df_path_n == 0)
	    // we have reached the end of the tree
	    node->df_choice_mem[lastdecision] = 0;
	else
	{
	    // the minimum amount of turns required to reach the end
	    size_t minimum_turns = SIZE_MAX;
	    for (size_t i = 0; i < node->df_path_n; i++)
	    {
		// recurse
		size_t t = test_charmatch_paths(node->df_decision[i],
							node->df_choice[i]) +
		    (lastdecision != node->df_choice[i] ? 1 : 0);
		if (t < minimum_turns)
		{
		    node->df_optimal_choice = i;
		    minimum_turns = t;
		}
	    }
	    node->df_choice_mem[lastdecision] = (int)minimum_turns;
	}
    }

    return (size_t)node->df_choice_mem[lastdecision];
}
