#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "gettext.h"
#include "config.h"
#include "commit.h"
#include "color.h"
#include "graph.h"
#include "revision.h"
#include "strvec.h"

/* Internal API */

/*
 * Output a padding line in the graph.
 * This is similar to graph_next_line().  However, it is guaranteed to
 * never print the current commit line.  Instead, if the commit line is
 * next, it will simply output a line of vertical padding, extending the
 * branch lines downwards, but leaving them otherwise unchanged.
 */
static void graph_padding_line(struct git_graph *graph, struct strbuf *sb);

/*
 * Print a strbuf.  If the graph is non-NULL, all lines but the first will be
 * prefixed with the graph output.
 *
 * If the strbuf ends with a newline, the output will end after this
 * newline.  A new graph line will not be printed after the final newline.
 * If the strbuf is empty, no output will be printed.
 *
 * Since the first line will not include the graph output, the caller is
 * responsible for printing this line's graph (perhaps via
 * graph_show_commit() or graph_show_oneline()) before calling
 * graph_show_strbuf().
 *
 * Note that unlike some other graph display functions, you must pass the file
 * handle directly. It is assumed that this is the same file handle as the
 * file specified by the graph diff options. This is necessary so that
 * graph_show_strbuf can be called even with a NULL graph.
 * If a NULL graph is supplied, the strbuf is printed as-is.
 */
static void graph_show_strbuf(struct git_graph *graph,
			      FILE *file,
			      struct strbuf const *sb);

/*
 * TODO:
 * - Limit the number of columns, similar to the way gitk does.
 *   If we reach more than a specified number of columns, omit
 *   sections of some columns.
 */

struct column {
	/*
	 * The parent commit of this column.
	 */
	struct commit *commit;
	/*
	 * The color to (optionally) print this column in.  This is an
	 * index into column_colors.
	 */
	unsigned short color;
};

enum graph_state {
	GRAPH_PADDING,
	GRAPH_SKIP,
	GRAPH_PRE_COMMIT,
	GRAPH_COMMIT,
	GRAPH_POST_MERGE,
	GRAPH_COLLAPSING
};

static void graph_show_line_prefix(const struct diff_options *diffopt)
{
	if (!diffopt || !diffopt->line_prefix)
		return;

	fputs(diffopt->line_prefix, diffopt->file);
}

static const char **column_colors;
static unsigned short column_colors_max;

static void parse_graph_colors_config(struct strvec *colors, const char *string)
{
	const char *end, *start;

	start = string;
	end = string + strlen(string);
	while (start < end) {
		const char *comma = strchrnul(start, ',');
		char color[COLOR_MAXLEN];

		if (!color_parse_mem(start, comma - start, color))
			strvec_push(colors, color);
		else
			warning(_("ignored invalid color '%.*s' in log.graphColors"),
				(int)(comma - start), start);
		start = comma + 1;
	}
	strvec_push(colors, GIT_COLOR_RESET);
}

void graph_set_column_colors(const char **colors, unsigned short colors_max)
{
	column_colors = colors;
	column_colors_max = colors_max;
}

static const char *column_get_color_code(unsigned short color)
{
	return column_colors[color];
}

struct graph_line {
	struct strbuf *buf;
	size_t width;
};

static inline void graph_line_addch(struct graph_line *line, int c)
{
	strbuf_addch(line->buf, c);
	line->width++;
}

static inline void graph_line_addchars(struct graph_line *line, int c, size_t n)
{
	strbuf_addchars(line->buf, c, n);
	line->width += n;
}

static inline void graph_line_addstr(struct graph_line *line, const char *s)
{
	strbuf_addstr(line->buf, s);
	line->width += strlen(s);
}

static inline void graph_line_addcolor(struct graph_line *line, unsigned short color)
{
	strbuf_addstr(line->buf, column_get_color_code(color));
}

static void graph_line_write_column(struct graph_line *line, const struct column *c,
				    char col_char)
{
	if (c->color < column_colors_max)
		graph_line_addcolor(line, c->color);
	graph_line_addch(line, col_char);
	if (c->color < column_colors_max)
		graph_line_addcolor(line, column_colors_max);
}

struct git_graph {
	/*
	 * The commit currently being processed
	 */
	struct commit *commit;
	/* The rev-info used for the current traversal */
	struct rev_info *revs;
	/*
	 * The number of interesting parents that this commit has.
	 *
	 * Note that this is not the same as the actual number of parents.
	 * This count excludes parents that won't be printed in the graph
	 * output, as determined by graph_is_interesting().
	 */
	int num_parents;
	/*
	 * The width of the graph output for this commit.
	 * All rows for this commit are padded to this width, so that
	 * messages printed after the graph output are aligned.
	 */
	int width;
	/*
	 * The next expansion row to print
	 * when state is GRAPH_PRE_COMMIT
	 */
	int expansion_row;
	/*
	 * The current output state.
	 * This tells us what kind of line graph_next_line() should output.
	 */
	enum graph_state state;
	/*
	 * The output state for the previous line of output.
	 * This is primarily used to determine how the first merge line
	 * should appear, based on the last line of the previous commit.
	 */
	enum graph_state prev_state;
	/*
	 * The index of the column that refers to this commit.
	 *
	 * If none of the incoming columns refer to this commit,
	 * this will be equal to num_columns.
	 */
	int commit_index;
	/*
	 * The commit_index for the previously displayed commit.
	 *
	 * This is used to determine how the first line of a merge
	 * graph output should appear, based on the last line of the
	 * previous commit.
	 */
	int prev_commit_index;
	/*
	 * Which layout variant to use to display merge commits. If the
	 * commit's first parent is known to be in a column to the left of the
	 * merge, then this value is 0 and we use the layout on the left.
	 * Otherwise, the value is 1 and the layout on the right is used. This
	 * field tells us how many columns the first parent occupies.
	 *
	 * 		0)			1)
	 *
	 * 		| | | *-.		| | *---.
	 * 		| |_|/|\ \		| | |\ \ \
	 * 		|/| | | | |		| | | | | *
	 */
	int merge_layout;
	/*
	 * The number of columns added to the graph by the current commit. For
	 * 2-way and octopus merges, this is usually one less than the
	 * number of parents:
	 *
	 * 		| | |			| |    \
	 *		| * |			| *---. \
	 *		| |\ \			| |\ \ \ \
	 *		| | | |         	| | | | | |
	 *
	 *		num_parents: 2		num_parents: 4
	 *		edges_added: 1		edges_added: 3
	 *
	 * For left-skewed merges, the first parent fuses with its neighbor and
	 * so one less column is added:
	 *
	 *		| | |			| |  \
	 *		| * |			| *-. \
	 *		|/| |			|/|\ \ \
	 *		| | |			| | | | |
	 *
	 *		num_parents: 2		num_parents: 4
	 *		edges_added: 0		edges_added: 2
	 *
	 * This number determines how edges to the right of the merge are
	 * displayed in commit and post-merge lines; if no columns have been
	 * added then a vertical line should be used where a right-tracking
	 * line would otherwise be used.
	 *
	 *		| * \			| * |
	 *		| |\ \			|/| |
	 *		| | * \			| * |
	 */
	int edges_added;
	/*
	 * The number of columns added by the previous commit, which is used to
	 * smooth edges appearing to the right of a commit in a commit line
	 * following a post-merge line.
	 */
	int prev_edges_added;
	/*
	 * The maximum number of columns that can be stored in the columns
	 * and new_columns arrays.  This is also half the number of entries
	 * that can be stored in the mapping and old_mapping arrays.
	 */
	int column_capacity;
	/*
	 * The number of columns (also called "branch lines" in some places)
	 */
	int num_columns;
	/*
	 * The number of columns in the new_columns array
	 */
	int num_new_columns;
	/*
	 * The number of entries in the mapping array
	 */
	int mapping_size;
	/*
	 * The column state before we output the current commit.
	 */
	struct column *columns;
	/*
	 * The new column state after we output the current commit.
	 * Only valid when state is GRAPH_COLLAPSING.
	 */
	struct column *new_columns;
	/*
	 * An array that tracks the current state of each
	 * character in the output line during state GRAPH_COLLAPSING.
	 * Each entry is -1 if this character is empty, or a non-negative
	 * integer if the character contains a branch line.  The value of
	 * the integer indicates the target position for this branch line.
	 * (I.e., this array maps the current column positions to their
	 * desired positions.)
	 *
	 * The maximum capacity of this array is always
	 * sizeof(int) * 2 * column_capacity.
	 */
	int *mapping;
	/*
	 * A copy of the contents of the mapping array from the last commit,
	 * which we use to improve the display of columns that are tracking
	 * from right to left through a commit line.  We also use this to
	 * avoid allocating a fresh array when we compute the next mapping.
	 */
	int *old_mapping;
	/*
	 * The current default column color being used.  This is
	 * stored as an index into the array column_colors.
	 */
	unsigned short default_column_color;

	/*
	 * Scratch buffer for generating prefixes to be used with
	 * diff_output_prefix_callback().
	 */
	struct strbuf prefix_buf;
};

static inline int graph_needs_truncation(struct git_graph *graph, int lane)
{
	int max = graph->revs->graph_max_lanes;
	/*
	 * Ignore values <= 0, meaning no limit.
	 */
	return max > 0 && lane >= max;
}

static const char *diff_output_prefix_callback(struct diff_options *opt, void *data)
{
	struct git_graph *graph = data;

	assert(opt);

	if (!graph)
		return opt->line_prefix;

	strbuf_reset(&graph->prefix_buf);
	if (opt->line_prefix)
		strbuf_addstr(&graph->prefix_buf, opt->line_prefix);
	graph_padding_line(graph, &graph->prefix_buf);
	return graph->prefix_buf.buf;
}

static const struct diff_options *default_diffopt;

void graph_setup_line_prefix(struct diff_options *diffopt)
{
	default_diffopt = diffopt;

	/* setup an output prefix callback if necessary */
	if (diffopt && !diffopt->output_prefix)
		diffopt->output_prefix = diff_output_prefix_callback;
}

struct git_graph *graph_init(struct rev_info *opt)
{
	struct git_graph *graph = xmalloc(sizeof(struct git_graph));

	if (!column_colors) {
		char *string;
		if (repo_config_get_string(opt->repo, "log.graphcolors", &string)) {
			/* not configured -- use default */
			graph_set_column_colors(column_colors_ansi,
						column_colors_ansi_max);
		} else {
			static struct strvec custom_colors = STRVEC_INIT;
			strvec_clear(&custom_colors);
			parse_graph_colors_config(&custom_colors, string);
			free(string);
			/* graph_set_column_colors takes a max-index, not a count */
			graph_set_column_colors(custom_colors.v,
						custom_colors.nr - 1);
		}
	}

	graph->commit = NULL;
	graph->revs = opt;
	graph->num_parents = 0;
	graph->expansion_row = 0;
	graph->state = GRAPH_PADDING;
	graph->prev_state = GRAPH_PADDING;
	graph->commit_index = 0;
	graph->prev_commit_index = 0;
	graph->merge_layout = 0;
	graph->edges_added = 0;
	graph->prev_edges_added = 0;
	graph->num_columns = 0;
	graph->num_new_columns = 0;
	graph->mapping_size = 0;
	/*
	 * Start the column color at the maximum value, since we'll
	 * always increment it for the first commit we output.
	 * This way we start at 0 for the first commit.
	 */
	graph->default_column_color = column_colors_max - 1;

	/*
	 * Allocate a reasonably large default number of columns
	 * We'll automatically grow columns later if we need more room.
	 */
	graph->column_capacity = 30;
	ALLOC_ARRAY(graph->columns, graph->column_capacity);
	ALLOC_ARRAY(graph->new_columns, graph->column_capacity);
	ALLOC_ARRAY(graph->mapping, 2 * graph->column_capacity);
	ALLOC_ARRAY(graph->old_mapping, 2 * graph->column_capacity);

	/*
	 * The diff output prefix callback, with this we can make
	 * all the diff output to align with the graph lines.
	 */
	strbuf_init(&graph->prefix_buf, 0);
	opt->diffopt.output_prefix = diff_output_prefix_callback;
	opt->diffopt.output_prefix_data = graph;

	return graph;
}

void graph_clear(struct git_graph *graph)
{
	if (!graph)
		return;

	free(graph->columns);
	free(graph->new_columns);
	free(graph->mapping);
	free(graph->old_mapping);
	strbuf_release(&graph->prefix_buf);
	free(graph);
}

static void graph_update_state(struct git_graph *graph, enum graph_state s)
{
	graph->prev_state = graph->state;
	graph->state = s;
}

static void graph_ensure_capacity(struct git_graph *graph, int num_columns)
{
	if (graph->column_capacity >= num_columns)
		return;

	do {
		graph->column_capacity *= 2;
	} while (graph->column_capacity < num_columns);

	REALLOC_ARRAY(graph->columns, graph->column_capacity);
	REALLOC_ARRAY(graph->new_columns, graph->column_capacity);
	REALLOC_ARRAY(graph->mapping, graph->column_capacity * 2);
	REALLOC_ARRAY(graph->old_mapping, graph->column_capacity * 2);
}

/*
 * Returns 1 if the commit will be printed in the graph output,
 * and 0 otherwise.
 */
static int graph_is_interesting(struct git_graph *graph, struct commit *commit)
{
	/*
	 * If revs->boundary is set, commits whose children have
	 * been shown are always interesting, even if they have the
	 * UNINTERESTING or TREESAME flags set.
	 */
	if (graph->revs && graph->revs->boundary) {
		if (commit->object.flags & CHILD_SHOWN)
			return 1;
	}

	/*
	 * Otherwise, use get_commit_action() to see if this commit is
	 * interesting
	 */
	return get_commit_action(graph->revs, commit) == commit_show;
}

static struct commit_list *next_interesting_parent(struct git_graph *graph,
						   struct commit_list *orig)
{
	struct commit_list *list;

	/*
	 * If revs->first_parent_only is set, only the first
	 * parent is interesting.  None of the others are.
	 */
	if (graph->revs->first_parent_only)
		return NULL;

	/*
	 * Return the next interesting commit after orig
	 */
	for (list = orig->next; list; list = list->next) {
		if (graph_is_interesting(graph, list->item))
			return list;
	}

	return NULL;
}

static struct commit_list *first_interesting_parent(struct git_graph *graph)
{
	struct commit_list *parents = graph->commit->parents;

	/*
	 * If this commit has no parents, ignore it
	 */
	if (!parents)
		return NULL;

	/*
	 * If the first parent is interesting, return it
	 */
	if (graph_is_interesting(graph, parents->item))
		return parents;

	/*
	 * Otherwise, call next_interesting_parent() to get
	 * the next interesting parent
	 */
	return next_interesting_parent(graph, parents);
}

static unsigned short graph_get_current_column_color(const struct git_graph *graph)
{
	if (!want_color(graph->revs->diffopt.use_color))
		return column_colors_max;
	return graph->default_column_color;
}

/*
 * Update the graph's default column color.
 */
static void graph_increment_column_color(struct git_graph *graph)
{
	graph->default_column_color = (graph->default_column_color + 1) %
		column_colors_max;
}

static unsigned short graph_find_commit_color(const struct git_graph *graph,
					      const struct commit *commit)
{
	int i;
	for (i = 0; i < graph->num_columns; i++) {
		if (graph->columns[i].commit == commit)
			return graph->columns[i].color;
	}
	return graph_get_current_column_color(graph);
}

static int graph_find_new_column_by_commit(struct git_graph *graph,
					   struct commit *commit)
{
	int i;
	for (i = 0; i < graph->num_new_columns; i++) {
		if (graph->new_columns[i].commit == commit)
			return i;
	}
	return -1;
}

static void graph_insert_into_new_columns(struct git_graph *graph,
					  struct commit *commit,
					  int idx)
{
	int i = graph_find_new_column_by_commit(graph, commit);
	int mapping_idx;

	/*
	 * If the commit is not already in the new_columns array, then add it
	 * and record it as being in the final column.
	 */
	if (i < 0) {
		i = graph->num_new_columns++;
		graph->new_columns[i].commit = commit;
		graph->new_columns[i].color = graph_find_commit_color(graph, commit);
	}

	if (graph->num_parents > 1 && idx > -1 && graph->merge_layout == -1) {
		/*
		 * If this is the first parent of a merge, choose a layout for
		 * the merge line based on whether the parent appears in a
		 * column to the left of the merge
		 */
		int dist, shift;

		dist = idx - i;
		shift = (dist > 1) ? 2 * dist - 3 : 1;

		graph->merge_layout = (dist > 0) ? 0 : 1;
		graph->edges_added = graph->num_parents + graph->merge_layout  - 2;

		mapping_idx = graph->width + (graph->merge_layout - 1) * shift;
		graph->width += 2 * graph->merge_layout;

	} else if (graph->edges_added > 0 && i == graph->mapping[graph->width - 2]) {
		/*
		 * If some columns have been added by a merge, but this commit
		 * was found in the last existing column, then adjust the
		 * numbers so that the two edges immediately join, i.e.:
		 *
		 *		* |		* |
		 *		|\ \	=>	|\|
		 *		| |/		| *
		 *		| *
		 */
		mapping_idx = graph->width - 2;
		graph->edges_added = -1;
	} else {
		mapping_idx = graph->width;
		graph->width += 2;
	}

	graph->mapping[mapping_idx] = i;
}

static void graph_update_columns(struct git_graph *graph)
{
	struct commit_list *parent;
	int max_new_columns;
	int i, seen_this, is_commit_in_columns;

	/*
	 * Swap graph->columns with graph->new_columns
	 * graph->columns contains the state for the previous commit,
	 * and new_columns now contains the state for our commit.
	 *
	 * We'll re-use the old columns array as storage to compute the new
	 * columns list for the commit after this one.
	 */
	SWAP(graph->columns, graph->new_columns);
	graph->num_columns = graph->num_new_columns;
	graph->num_new_columns = 0;

	/*
	 * Now update new_columns and mapping with the information for the
	 * commit after this one.
	 *
	 * First, make sure we have enough room.  At most, there will
	 * be graph->num_columns + graph->num_parents columns for the next
	 * commit.
	 */
	max_new_columns = graph->num_columns + graph->num_parents;
	graph_ensure_capacity(graph, max_new_columns);

	/*
	 * Clear out graph->mapping
	 */
	graph->mapping_size = 2 * max_new_columns;
	for (i = 0; i < graph->mapping_size; i++)
		graph->mapping[i] = -1;

	graph->width = 0;
	graph->prev_edges_added = graph->edges_added;
	graph->edges_added = 0;

	/*
	 * Populate graph->new_columns and graph->mapping
	 *
	 * Some of the parents of this commit may already be in
	 * graph->columns.  If so, graph->new_columns should only contain a
	 * single entry for each such commit.  graph->mapping should
	 * contain information about where each current branch line is
	 * supposed to end up after the collapsing is performed.
	 */
	seen_this = 0;
	is_commit_in_columns = 1;
	for (i = 0; i <= graph->num_columns; i++) {
		struct commit *col_commit;
		if (i == graph->num_columns) {
			if (seen_this)
				break;
			is_commit_in_columns = 0;
			col_commit = graph->commit;
		} else {
			col_commit = graph->columns[i].commit;
		}

		if (col_commit == graph->commit) {
			seen_this = 1;
			graph->commit_index = i;
			graph->merge_layout = -1;
			for (parent = first_interesting_parent(graph);
			     parent;
			     parent = next_interesting_parent(graph, parent)) {
				/*
				 * If this is a merge, or the start of a new
				 * childless column, increment the current
				 * color.
				 */
				if (graph->num_parents > 1 ||
				    !is_commit_in_columns) {
					graph_increment_column_color(graph);
				}
				graph_insert_into_new_columns(graph, parent->item, i);
			}
			/*
			 * We always need to increment graph->width by at
			 * least 2, even if it has no interesting parents.
			 * The current commit always takes up at least 2
			 * spaces.
			 */
			if (graph->num_parents == 0)
				graph->width += 2;
		} else {
			graph_insert_into_new_columns(graph, col_commit, -1);
		}
	}

	/*
	 * If graph_max_lanes is set, cap the width
	 */
	if (graph->revs->graph_max_lanes > 0) {
		/*
		 * width of "| " per lanes plus truncation mark "~ ".
		 * Allow commits from merges to align to the merged lane.
		 */
		int max_width = graph->revs->graph_max_lanes * 2 + 2;
		if (graph->width > max_width)
			graph->width = max_width;
	}

	/*
	 * Shrink mapping_size to be the minimum necessary
	 */
	while (graph->mapping_size > 1 &&
	       graph->mapping[graph->mapping_size - 1] < 0)
		graph->mapping_size--;
}

static int graph_num_dashed_parents(struct git_graph *graph)
{
	return graph->num_parents + graph->merge_layout - 3;
}

static int graph_num_expansion_rows(struct git_graph *graph)
{
	/*
	 * Normally, we need two expansion rows for each dashed parent line from
	 * an octopus merge:
	 *
	 * 		| *
	 * 		| |\
	 * 		| | \
	 * 		| |  \
	 * 		| *-. \
	 * 		| |\ \ \
	 *
	 * If the merge is skewed to the left, then its parents occupy one less
	 * column, and we don't need as many expansion rows to route around it;
	 * in some cases that means we don't need any expansion rows at all:
	 *
	 * 		| *
	 * 		| |\
	 * 		| * \
	 * 		|/|\ \
	 */
	return graph_num_dashed_parents(graph) * 2;
}

static int graph_needs_pre_commit_line(struct git_graph *graph)
{
	return graph->num_parents >= 3 &&
	       graph->commit_index < (graph->num_columns - 1) &&
	       graph->expansion_row < graph_num_expansion_rows(graph);
}

void graph_update(struct git_graph *graph, struct commit *commit)
{
	struct commit_list *parent;

	/*
	 * Set the new commit
	 */
	graph->commit = commit;

	/*
	 * Count how many interesting parents this commit has
	 */
	graph->num_parents = 0;
	for (parent = first_interesting_parent(graph);
	     parent;
	     parent = next_interesting_parent(graph, parent))
	{
		graph->num_parents++;
	}

	/*
	 * Store the old commit_index in prev_commit_index.
	 * graph_update_columns() will update graph->commit_index for this
	 * commit.
	 */
	graph->prev_commit_index = graph->commit_index;

	/*
	 * Call graph_update_columns() to update
	 * columns, new_columns, and mapping.
	 */
	graph_update_columns(graph);

	graph->expansion_row = 0;

	/*
	 * Update graph->state.
	 * Note that we don't call graph_update_state() here, since
	 * we don't want to update graph->prev_state.  No line for
	 * graph->state was ever printed.
	 *
	 * If the previous commit didn't get to the GRAPH_PADDING state,
	 * it never finished its output.  Goto GRAPH_SKIP, to print out
	 * a line to indicate that portion of the graph is missing.
	 *
	 * If there are 3 or more parents, we may need to print extra rows
	 * before the commit, to expand the branch lines around it and make
	 * room for it.  We need to do this only if there is a branch row
	 * (or more) to the right of this commit.
	 *
	 * If there are less than 3 parents, we can immediately print the
	 * commit line.
	 */
	if (graph->state != GRAPH_PADDING)
		graph->state = GRAPH_SKIP;
	else if (graph_needs_pre_commit_line(graph))
		graph->state = GRAPH_PRE_COMMIT;
	else
		graph->state = GRAPH_COMMIT;
}

static int graph_is_mapping_correct(struct git_graph *graph)
{
	int i;

	/*
	 * The mapping is up to date if each entry is at its target,
	 * or is 1 greater than its target.
	 * (If it is 1 greater than the target, '/' will be printed, so it
	 * will look correct on the next row.)
	 */
	for (i = 0; i < graph->mapping_size; i++) {
		int target = graph->mapping[i];
		if (target < 0)
			continue;
		if (target == (i / 2))
			continue;
		return 0;
	}

	return 1;
}

static void graph_pad_horizontally(struct git_graph *graph, struct graph_line *line)
{
	/*
	 * Add additional spaces to the end of the strbuf, so that all
	 * lines for a particular commit have the same width.
	 *
	 * This way, fields printed to the right of the graph will remain
	 * aligned for the entire commit.
	 */
	if (line->width < graph->width)
		graph_line_addchars(line, ' ', graph->width - line->width);
}

static void graph_output_padding_line(struct git_graph *graph,
				      struct graph_line *line)
{
	int i;

	/*
	 * Output a padding row, that leaves all branch lines unchanged
	 */
	for (i = 0; i < graph->num_new_columns; i++) {
		if (graph_needs_truncation(graph, i)) {
			graph_line_addstr(line, "~ ");
			break;
		}
		graph_line_write_column(line, &graph->new_columns[i], '|');
		graph_line_addch(line, ' ');
	}
}


int graph_width(struct git_graph *graph)
{
	return graph->width;
}


static void graph_output_skip_line(struct git_graph *graph, struct graph_line *line)
{
	/*
	 * Output an ellipsis to indicate that a portion
	 * of the graph is missing.
	 */
	graph_line_addstr(line, "...");

	if (graph_needs_pre_commit_line(graph))
		graph_update_state(graph, GRAPH_PRE_COMMIT);
	else
		graph_update_state(graph, GRAPH_COMMIT);
}

static void graph_output_pre_commit_line(struct git_graph *graph,
					 struct graph_line *line)
{
	int i, seen_this;

	/*
	 * This function formats a row that increases the space around a commit
	 * with multiple parents, to make room for it.  It should only be
	 * called when there are 3 or more parents.
	 *
	 * We need 2 extra rows for every parent over 2.
	 */
	assert(graph->num_parents >= 3);

	/*
	 * graph->expansion_row tracks the current expansion row we are on.
	 * It should be in the range [0, num_expansion_rows - 1]
	 */
	assert(0 <= graph->expansion_row &&
	       graph->expansion_row < graph_num_expansion_rows(graph));

	/*
	 * Output the row
	 */
	seen_this = 0;
	for (i = 0; i < graph->num_columns; i++) {
		struct column *col = &graph->columns[i];
		if (col->commit == graph->commit) {
			seen_this = 1;
			graph_line_write_column(line, col, '|');
			graph_line_addchars(line, ' ', graph->expansion_row);
		} else if (seen_this && graph_needs_truncation(graph, i)) {
			graph_line_addstr(line, "~ ");
			break;
		} else if (seen_this && (graph->expansion_row == 0)) {
			/*
			 * This is the first line of the pre-commit output.
			 * If the previous commit was a merge commit and
			 * ended in the GRAPH_POST_MERGE state, all branch
			 * lines after graph->prev_commit_index were
			 * printed as "\" on the previous line.  Continue
			 * to print them as "\" on this line.  Otherwise,
			 * print the branch lines as "|".
			 */
			if (graph->prev_state == GRAPH_POST_MERGE &&
			    graph->prev_commit_index < i)
				graph_line_write_column(line, col, '\\');
			else
				graph_line_write_column(line, col, '|');
		} else if (seen_this && (graph->expansion_row > 0)) {
			graph_line_write_column(line, col, '\\');
		} else {
			graph_line_write_column(line, col, '|');
		}
		graph_line_addch(line, ' ');
	}

	/*
	 * Increment graph->expansion_row,
	 * and move to state GRAPH_COMMIT if necessary
	 */
	graph->expansion_row++;
	if (!graph_needs_pre_commit_line(graph))
		graph_update_state(graph, GRAPH_COMMIT);
}

static void graph_output_commit_char(struct git_graph *graph, struct graph_line *line)
{
	/*
	 * For boundary commits, print 'o'
	 * (We should only see boundary commits when revs->boundary is set.)
	 */
	if (graph->commit->object.flags & BOUNDARY) {
		assert(graph->revs->boundary);
		graph_line_addch(line, 'o');
		return;
	}

	/*
	 * get_revision_mark() handles all other cases without assert()
	 */
	graph_line_addstr(line, get_revision_mark(graph->revs, graph->commit));
}

/*
 * Draw the horizontal dashes of an octopus merge.
 */
static void graph_draw_octopus_merge(struct git_graph *graph, struct graph_line *line)
{
	/*
	 * The parents of a merge commit can be arbitrarily reordered as they
	 * are mapped onto display columns, for example this is a valid merge:
	 *
	 *	| | *---.
	 *	| | |\ \ \
	 *	| | |/ / /
	 *	| |/| | /
	 *	| |_|_|/
	 *	|/| | |
	 *	3 1 0 2
	 *
	 * The numbers denote which parent of the merge each visual column
	 * corresponds to; we can't assume that the parents will initially
	 * display in the order given by new_columns.
	 *
	 * To find the right color for each dash, we need to consult the
	 * mapping array, starting from the column 2 places to the right of the
	 * merge commit, and use that to find out which logical column each
	 * edge will collapse to.
	 *
	 * Commits are rendered once all edges have collapsed to their correct
	 * logcial column, so commit_index gives us the right visual offset for
	 * the merge commit.
	 */

	int i, j;
	struct column *col;

	int dashed_parents = graph_num_dashed_parents(graph);

	for (i = 0; i < dashed_parents; i++) {
		j = graph->mapping[(graph->commit_index + i + 2) * 2];
		col = &graph->new_columns[j];

		graph_line_write_column(line, col, '-');

		/*
		 * Commit is at commit_index, each iteration move one lane to
		 * the right from the commit.
		 */
		if (graph_needs_truncation(graph, graph->commit_index + 1 + i)) {
			graph_line_addstr(line, "~ ");
			break;
		}

		graph_line_write_column(line, col, (i == dashed_parents - 1) ? '.' : '-');
	}

	return;
}

static void graph_output_commit_line(struct git_graph *graph, struct graph_line *line)
{
	int seen_this = 0;
	int i;

	/*
	 * Output the row containing this commit
	 * Iterate up to and including graph->num_columns,
	 * since the current commit may not be in any of the existing
	 * columns.  (This happens when the current commit doesn't have any
	 * children that we have already processed.)
	 */
	seen_this = 0;
	for (i = 0; i <= graph->num_columns; i++) {
		struct column *col = &graph->columns[i];
		struct commit *col_commit;
		if (i == graph->num_columns) {
			if (seen_this)
				break;
			col_commit = graph->commit;
		} else {
			col_commit = graph->columns[i].commit;
		}

		if (col_commit == graph->commit) {
			seen_this = 1;
			graph_output_commit_char(graph, line);

			if (graph_needs_truncation(graph, i)) {
				graph_line_addch(line, ' ');
				break;
			}

			if (graph->num_parents > 2)
				graph_draw_octopus_merge(graph, line);
		} else if (graph_needs_truncation(graph, i)) {
			graph_line_addstr(line, "~ ");
			seen_this = 1;
			break;
		} else if (seen_this && (graph->edges_added > 1)) {
			graph_line_write_column(line, col, '\\');
		} else if (seen_this && (graph->edges_added == 1)) {
			/*
			 * This is either a right-skewed 2-way merge
			 * commit, or a left-skewed 3-way merge.
			 * There is no GRAPH_PRE_COMMIT stage for such
			 * merges, so this is the first line of output
			 * for this commit.  Check to see what the previous
			 * line of output was.
			 *
			 * If it was GRAPH_POST_MERGE, the branch line
			 * coming into this commit may have been '\',
			 * and not '|' or '/'.  If so, output the branch
			 * line as '\' on this line, instead of '|'.  This
			 * makes the output look nicer.
			 */
			if (graph->prev_state == GRAPH_POST_MERGE &&
			    graph->prev_edges_added > 0 &&
			    graph->prev_commit_index < i)
				graph_line_write_column(line, col, '\\');
			else
				graph_line_write_column(line, col, '|');
		} else if (graph->prev_state == GRAPH_COLLAPSING &&
			   graph->old_mapping[2 * i + 1] == i &&
			   graph->mapping[2 * i] < i) {
			graph_line_write_column(line, col, '/');
		} else {
			graph_line_write_column(line, col, '|');
		}
		graph_line_addch(line, ' ');
	}

	/*
	 * Update graph->state
	 *
	 * If the commit is a merge and the first parent is in a visible lane,
	 * then the GRAPH_POST_MERGE is needed to draw the merge lane.
	 *
	 * If the commit is over the truncation limit, but the first parent is on
	 * a visible lane, then we still need the merge lane but truncated.
	 *
	 * If both commit and first parent are over the truncation limit, then
	 * there's no need to draw the merge lane because it would work as a
	 * padding lane.
	 */
	if (graph->num_parents > 1) {
		if (!graph_needs_truncation(graph, graph->commit_index)) {
			graph_update_state(graph, GRAPH_POST_MERGE);
		} else {
			struct commit_list *p = first_interesting_parent(graph);
			int lane;

			/*
			 * graph->num_parents are found using first_interesting_parent
			 * and next_interesting_parent so it can't be a scenario
			 * where num_parents > 1 and there are no interesting parents
			 */
			if (!p)
				BUG("num_parents > 1 but no interesting parent");

			lane = graph_find_new_column_by_commit(graph, p->item);

			if (!graph_needs_truncation(graph, lane))
				graph_update_state(graph, GRAPH_POST_MERGE);
			else if (graph_is_mapping_correct(graph))
				graph_update_state(graph, GRAPH_PADDING);
			else
				graph_update_state(graph, GRAPH_COLLAPSING);
		}
	} else if (graph_is_mapping_correct(graph)) {
		graph_update_state(graph, GRAPH_PADDING);
	} else {
		graph_update_state(graph, GRAPH_COLLAPSING);
	}
}

static const char merge_chars[] = {'/', '|', '\\'};

static void graph_output_post_merge_line(struct git_graph *graph, struct graph_line *line)
{
	int seen_this = 0;
	int i, j;

	struct commit_list *first_parent = first_interesting_parent(graph);
	struct column *parent_col = NULL;

	/*
	 * Output the post-merge row
	 */
	for (i = 0; i <= graph->num_columns; i++) {
		struct column *col = &graph->columns[i];
		struct commit *col_commit;
		if (i == graph->num_columns) {
			if (seen_this)
				break;
			col_commit = graph->commit;
		} else {
			col_commit = col->commit;
		}

		if (col_commit == graph->commit) {
			/*
			 * Since the current commit is a merge find
			 * the columns for the parent commits in
			 * new_columns and use those to format the
			 * edges.
			 */
			struct commit_list *parents = first_parent;
			int par_column;
			int idx = graph->merge_layout;
			char c;
			int truncated = 0;
			seen_this = 1;

			for (j = 0; j < graph->num_parents; j++) {
				par_column = graph_find_new_column_by_commit(graph, parents->item);
				assert(par_column >= 0);

				c = merge_chars[idx];
				graph_line_write_column(line, &graph->new_columns[par_column], c);

				/*
				 * j counts parents, it needs to be halved to be
				 * comparable with i. Don't truncate if there are
				 * no more lanes to print (end of the lane)
				 */
				if (graph_needs_truncation(graph, j / 2 + i) &&
				    j / 2 + i <= graph->num_columns) {
					if ((j + i * 2) % 2 != 0)
						graph_line_addch(line, ' ');
					graph_line_addstr(line, "~ ");
					truncated = 1;
					break;
				}

				if (idx == 2) {
					/*
					 * Check if the next lane needs truncation
					 * to avoid having the padding doubled
					 */
					if (graph_needs_truncation(graph, (j + 1) / 2 + i) &&
					    j < graph->num_parents - 1) {
						graph_line_addstr(line, "~ ");
						truncated = 1;
						break;
					} else if (graph->edges_added > 0 || j < graph->num_parents - 1)
						graph_line_addch(line, ' ');
				} else {
					idx++;
				}
				parents = next_interesting_parent(graph, parents);
			}
			if (truncated)
				break;
			if (graph->edges_added == 0)
				graph_line_addch(line, ' ');
		} else if (graph_needs_truncation(graph, i)) {
			graph_line_addstr(line, "~ ");
			break;
		} else if (seen_this) {
			if (graph->edges_added > 0)
				graph_line_write_column(line, col, '\\');
			else
				graph_line_write_column(line, col, '|');
			/*
			 * If it's between two lanes and next would be truncated,
			 * don't add space padding.
			 */
			if (!graph_needs_truncation(graph, i + 1))
				graph_line_addch(line, ' ');
		} else {
			graph_line_write_column(line, col, '|');
			if (graph->merge_layout != 0 || i != graph->commit_index - 1) {
				if (parent_col)
					graph_line_write_column(
						line, parent_col, '_');
				else
					graph_line_addch(line, ' ');
			}
		}

		if (col_commit == first_parent->item)
			parent_col = col;
	}

	/*
	 * Update graph->state
	 */
	if (graph_is_mapping_correct(graph))
		graph_update_state(graph, GRAPH_PADDING);
	else
		graph_update_state(graph, GRAPH_COLLAPSING);
}

static void graph_output_collapsing_line(struct git_graph *graph, struct graph_line *line)
{
	int i;
	short used_horizontal = 0;
	int horizontal_edge = -1;
	int horizontal_edge_target = -1;
	int truncated = 0;

	/*
	 * Swap the mapping and old_mapping arrays
	 */
	SWAP(graph->mapping, graph->old_mapping);

	/*
	 * Clear out the mapping array
	 */
	for (i = 0; i < graph->mapping_size; i++)
		graph->mapping[i] = -1;

	for (i = 0; i < graph->mapping_size; i++) {
		int target = graph->old_mapping[i];
		if (target < 0)
			continue;

		/*
		 * Since update_columns() always inserts the leftmost
		 * column first, each branch's target location should
		 * always be either its current location or to the left of
		 * its current location.
		 *
		 * We never have to move branches to the right.  This makes
		 * the graph much more legible, since whenever branches
		 * cross, only one is moving directions.
		 */
		assert(target * 2 <= i);

		if (target * 2 == i) {
			/*
			 * This column is already in the
			 * correct place
			 */
			assert(graph->mapping[i] == -1);
			graph->mapping[i] = target;
		} else if (graph->mapping[i - 1] < 0) {
			/*
			 * Nothing is to the left.
			 * Move to the left by one
			 */
			graph->mapping[i - 1] = target;
			/*
			 * If there isn't already an edge moving horizontally
			 * select this one.
			 */
			if (horizontal_edge == -1) {
				int j;
				horizontal_edge = i;
				horizontal_edge_target = target;
				/*
				 * The variable target is the index of the graph
				 * column, and therefore target*2+3 is the
				 * actual screen column of the first horizontal
				 * line.
				 */
				for (j = (target * 2)+3; j < (i - 2); j += 2)
					graph->mapping[j] = target;
			}
		} else if (graph->mapping[i - 1] == target) {
			/*
			 * There is a branch line to our left
			 * already, and it is our target.  We
			 * combine with this line, since we share
			 * the same parent commit.
			 *
			 * We don't have to add anything to the
			 * output or mapping, since the
			 * existing branch line has already taken
			 * care of it.
			 */
		} else {
			/*
			 * There is a branch line to our left,
			 * but it isn't our target.  We need to
			 * cross over it.
			 *
			 * The space just to the left of this
			 * branch should always be empty.
			 */
			assert(graph->mapping[i - 1] > target);
			assert(graph->mapping[i - 2] < 0);
			graph->mapping[i - 2] = target;
			/*
			 * Mark this branch as the horizontal edge to
			 * prevent any other edges from moving
			 * horizontally.
			 */
			if (horizontal_edge == -1) {
				int j;
				horizontal_edge_target = target;
				horizontal_edge = i - 1;

				for (j = (target * 2) + 3; j < (i - 2); j += 2)
					graph->mapping[j] = target;
			}
		}
	}

	/*
	 * Copy the current mapping array into old_mapping
	 */
	COPY_ARRAY(graph->old_mapping, graph->mapping, graph->mapping_size);

	/*
	 * The new mapping may be 1 smaller than the old mapping
	 */
	if (graph->mapping[graph->mapping_size - 1] < 0)
		graph->mapping_size--;

	/*
	 * Output out a line based on the new mapping info
	 */
	for (i = 0; i < graph->mapping_size; i++) {
		int target = graph->mapping[i];

		if (!truncated && graph_needs_truncation(graph, i / 2)) {
			graph_line_addstr(line, "~ ");
			truncated = 1;
		}

		if (target < 0) {
			if (!truncated)
				graph_line_addch(line, ' ');
		} else if (target * 2 == i) {
			if (!truncated)
				graph_line_write_column(line, &graph->new_columns[target], '|');
		} else if (target == horizontal_edge_target &&
			   i != horizontal_edge - 1) {
			/*
			 * Set the mappings for all but the
			 * first segment to -1 so that they
			 * won't continue into the next line.
			 */
			if (i != (target * 2)+3)
				graph->mapping[i] = -1;
			used_horizontal = 1;
			if (!truncated)
				graph_line_write_column(line, &graph->new_columns[target], '_');
		} else {
			if (used_horizontal && i < horizontal_edge)
				graph->mapping[i] = -1;
			if (!truncated)
				graph_line_write_column(line, &graph->new_columns[target], '/');
		}
	}

	/*
	 * If graph->mapping indicates that all of the branch lines
	 * are already in the correct positions, we are done.
	 * Otherwise, we need to collapse some branch lines together.
	 */
	if (graph_is_mapping_correct(graph))
		graph_update_state(graph, GRAPH_PADDING);
}

int graph_next_line(struct git_graph *graph, struct strbuf *sb)
{
	int shown_commit_line = 0;
	struct graph_line line = { .buf = sb, .width = 0 };

	/*
	 * We could conceivable be called with a NULL commit
	 * if our caller has a bug, and invokes graph_next_line()
	 * immediately after graph_init(), without first calling
	 * graph_update().  Return without outputting anything in this
	 * case.
	 */
	if (!graph->commit)
		return -1;

	switch (graph->state) {
	case GRAPH_PADDING:
		graph_output_padding_line(graph, &line);
		break;
	case GRAPH_SKIP:
		graph_output_skip_line(graph, &line);
		break;
	case GRAPH_PRE_COMMIT:
		graph_output_pre_commit_line(graph, &line);
		break;
	case GRAPH_COMMIT:
		graph_output_commit_line(graph, &line);
		shown_commit_line = 1;
		break;
	case GRAPH_POST_MERGE:
		graph_output_post_merge_line(graph, &line);
		break;
	case GRAPH_COLLAPSING:
		graph_output_collapsing_line(graph, &line);
		break;
	}

	graph_pad_horizontally(graph, &line);
	return shown_commit_line;
}

static void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
{
	int i;
	struct graph_line line = { .buf = sb, .width = 0 };

	if (graph->state != GRAPH_COMMIT) {
		graph_next_line(graph, sb);
		return;
	}

	/*
	 * Output the row containing this commit
	 * Iterate up to and including graph->num_columns,
	 * since the current commit may not be in any of the existing
	 * columns.  (This happens when the current commit doesn't have any
	 * children that we have already processed.)
	 */
	for (i = 0; i < graph->num_columns; i++) {
		struct column *col = &graph->columns[i];

		if (graph_needs_truncation(graph, i)) {
			graph_line_addstr(&line, "~ ");
			break;
		}

		graph_line_write_column(&line, col, '|');

		if (col->commit == graph->commit && graph->num_parents > 2) {
			int len = (graph->num_parents - 2) * 2;
			graph_line_addchars(&line, ' ', len);
		} else {
			graph_line_addch(&line, ' ');
		}
	}

	graph_pad_horizontally(graph, &line);

	/*
	 * Update graph->prev_state since we have output a padding line
	 */
	graph->prev_state = GRAPH_PADDING;
}

int graph_is_commit_finished(struct git_graph const *graph)
{
	return (graph->state == GRAPH_PADDING);
}

void graph_show_commit(struct git_graph *graph)
{
	struct strbuf msgbuf = STRBUF_INIT;
	int shown_commit_line = 0;

	graph_show_line_prefix(default_diffopt);

	if (!graph)
		return;

	/*
	 * When showing a diff of a merge against each of its parents, we
	 * are called once for each parent without graph_update having been
	 * called.  In this case, simply output a single padding line.
	 */
	if (graph_is_commit_finished(graph)) {
		graph_show_padding(graph);
		shown_commit_line = 1;
	}

	while (!shown_commit_line && !graph_is_commit_finished(graph)) {
		shown_commit_line = graph_next_line(graph, &msgbuf);
		fwrite(msgbuf.buf, sizeof(char), msgbuf.len,
			graph->revs->diffopt.file);
		if (!shown_commit_line) {
			putc('\n', graph->revs->diffopt.file);
			graph_show_line_prefix(&graph->revs->diffopt);
		}
		strbuf_setlen(&msgbuf, 0);
	}

	strbuf_release(&msgbuf);
}

void graph_show_oneline(struct git_graph *graph)
{
	struct strbuf msgbuf = STRBUF_INIT;

	graph_show_line_prefix(default_diffopt);

	if (!graph)
		return;

	graph_next_line(graph, &msgbuf);
	fwrite(msgbuf.buf, sizeof(char), msgbuf.len, graph->revs->diffopt.file);
	strbuf_release(&msgbuf);
}

void graph_show_padding(struct git_graph *graph)
{
	struct strbuf msgbuf = STRBUF_INIT;

	graph_show_line_prefix(default_diffopt);

	if (!graph)
		return;

	graph_padding_line(graph, &msgbuf);
	fwrite(msgbuf.buf, sizeof(char), msgbuf.len, graph->revs->diffopt.file);
	strbuf_release(&msgbuf);
}

int graph_show_remainder(struct git_graph *graph)
{
	struct strbuf msgbuf = STRBUF_INIT;
	int shown = 0;

	graph_show_line_prefix(default_diffopt);

	if (!graph)
		return 0;

	if (graph_is_commit_finished(graph))
		return 0;

	for (;;) {
		graph_next_line(graph, &msgbuf);
		fwrite(msgbuf.buf, sizeof(char), msgbuf.len,
			graph->revs->diffopt.file);
		strbuf_setlen(&msgbuf, 0);
		shown = 1;

		if (!graph_is_commit_finished(graph)) {
			putc('\n', graph->revs->diffopt.file);
			graph_show_line_prefix(&graph->revs->diffopt);
		} else {
			break;
		}
	}
	strbuf_release(&msgbuf);

	return shown;
}

static void graph_show_strbuf(struct git_graph *graph,
			      FILE *file,
			      struct strbuf const *sb)
{
	char *p;

	/*
	 * Print the strbuf line by line,
	 * and display the graph info before each line but the first.
	 */
	p = sb->buf;
	while (p) {
		size_t len;
		char *next_p = strchr(p, '\n');
		if (next_p) {
			next_p++;
			len = next_p - p;
		} else {
			len = (sb->buf + sb->len) - p;
		}
		fwrite(p, sizeof(char), len, file);
		if (next_p && *next_p != '\0')
			graph_show_oneline(graph);
		p = next_p;
	}
}

void graph_show_commit_msg(struct git_graph *graph,
			   FILE *file,
			   struct strbuf const *sb)
{
	int newline_terminated;

	/*
	 * Show the commit message
	 */
	graph_show_strbuf(graph, file, sb);

	if (!graph)
		return;

	newline_terminated = (sb->len && sb->buf[sb->len - 1] == '\n');

	/*
	 * If there is more output needed for this commit, show it now
	 */
	if (!graph_is_commit_finished(graph)) {
		/*
		 * If sb doesn't have a terminating newline, print one now,
		 * so we can start the remainder of the graph output on a
		 * new line.
		 */
		if (!newline_terminated)
			putc('\n', file);

		graph_show_remainder(graph);

		/*
		 * If sb ends with a newline, our output should too.
		 */
		if (newline_terminated)
			putc('\n', file);
	}
}
