/*
 * table.c - functions handling the data at the table level
 *
 * Copyright (C) 2010-2014 Karel Zak <kzak@redhat.com>
 * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com>
 * Copyright (C) 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */

/**
 * SECTION: table
 * @title: Table
 * @short_description: container for rows and columns
 *
 * Table data manipulation API.
 */


#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <ctype.h>

#include "nls.h"
#include "ttyutils.h"
#include "smartcolsP.h"

#ifdef HAVE_WIDECHAR
#define UTF_V	"\342\224\202"	/* U+2502, Vertical line drawing char */
#define UTF_VR	"\342\224\234"	/* U+251C, Vertical and right */
#define UTF_H	"\342\224\200"	/* U+2500, Horizontal */
#define UTF_UR	"\342\224\224"	/* U+2514, Up and right */
#endif /* !HAVE_WIDECHAR */

#define is_last_column(_tb, _cl) \
		list_entry_is_last(&(_cl)->cl_columns, &(_tb)->tb_columns)


static void check_padding_debug(struct libscols_table *tb)
{
	const char *str;

	assert(libsmartcols_debug_mask);	/* debug has to be enabled! */

	str = getenv("LIBSMARTCOLS_DEBUG_PADDING");
	if (!str || (strcmp(str, "on") != 0 && strcmp(str, "1") != 0))
		return;

	DBG(INIT, ul_debugobj(tb, "padding debug: ENABLE"));
	tb->padding_debug = 1;
}

/**
 * scols_new_table:
 *
 * Returns: A newly allocated table.
 */
struct libscols_table *scols_new_table(void)
{
	struct libscols_table *tb;
	int c, l;

	tb = calloc(1, sizeof(struct libscols_table));
	if (!tb)
		return NULL;

	tb->refcount = 1;
	tb->out = stdout;

	get_terminal_dimension(&c, &l);
	tb->termwidth  = c > 0 ? c : 80;
	tb->termheight = l > 0 ? l : 24;

	INIT_LIST_HEAD(&tb->tb_lines);
	INIT_LIST_HEAD(&tb->tb_columns);

	DBG(TAB, ul_debugobj(tb, "alloc"));
	ON_DBG(INIT, check_padding_debug(tb));

	return tb;
}

/**
 * scols_ref_table:
 * @tb: a pointer to a struct libscols_table instance
 *
 * Increases the refcount of @tb.
 */
void scols_ref_table(struct libscols_table *tb)
{
	if (tb)
		tb->refcount++;
}

/**
 * scols_unref_table:
 * @tb: a pointer to a struct libscols_table instance
 *
 * Decreases the refcount of @tb. When the count falls to zero, the instance
 * is automatically deallocated.
 */
void scols_unref_table(struct libscols_table *tb)
{
	if (tb && (--tb->refcount <= 0)) {
		DBG(TAB, ul_debugobj(tb, "dealloc"));
		scols_table_remove_lines(tb);
		scols_table_remove_columns(tb);
		scols_unref_symbols(tb->symbols);
		scols_reset_cell(&tb->title);
		free(tb->linesep);
		free(tb->colsep);
		free(tb->name);
		free(tb);
	}
}

/**
 * scols_table_set_name:
 * @tb: a pointer to a struct libscols_table instance
 * @name: a name
 *
 * The table name is used for example for JSON top level object name.
 *
 * Returns: 0, a negative number in case of an error.
 *
 * Since: 2.27
 */
int scols_table_set_name(struct libscols_table *tb, const char *name)
{
	return strdup_to_struct_member(tb, name, name);
}

/**
 * scols_table_get_name:
 * @tb: a pointer to a struct libscols_table instance
 *
 * Returns: The current name setting of the table @tb
 *
 * Since: 2.29
 */
const char *scols_table_get_name(const struct libscols_table *tb)
{
	return tb->name;
}

/**
 * scols_table_get_title:
 * @tb: a pointer to a struct libscols_table instance
 *
 * The returned pointer is possible to modify by cell functions. Note that
 * title output alignment on non-tty is hardcoded to 80 output chars. For the
 * regular terminal it's based on terminal width.
 *
 * Returns: Title of the table, or NULL in case of blank title.
 *
 * Since: 2.28
 */
struct libscols_cell *scols_table_get_title(struct libscols_table *tb)
{
	return &tb->title;
}

/**
 * scols_table_add_column:
 * @tb: a pointer to a struct libscols_table instance
 * @cl: a pointer to a struct libscols_column instance
 *
 * Adds @cl to @tb's column list. The column cannot be shared between more
 * tables.
 *
 * Returns: 0, a negative number in case of an error.
 */
int scols_table_add_column(struct libscols_table *tb, struct libscols_column *cl)
{
	struct libscols_iter itr;
	struct libscols_line *ln;
	int rc = 0;

	if (!tb || !cl || cl->table)
		return -EINVAL;

	if (cl->flags & SCOLS_FL_TREE)
		tb->ntreecols++;

	DBG(TAB, ul_debugobj(tb, "add column"));
	list_add_tail(&cl->cl_columns, &tb->tb_columns);
	cl->seqnum = tb->ncols++;
	cl->table = tb;
	scols_ref_column(cl);

	if (list_empty(&tb->tb_lines))
		return 0;

	scols_reset_iter(&itr, SCOLS_ITER_FORWARD);

	/* Realloc line cell arrays
	 */
	while (scols_table_next_line(tb, &itr, &ln) == 0) {
		rc = scols_line_alloc_cells(ln, tb->ncols);
		if (rc)
			break;
	}

	return rc;
}

/**
 * scols_table_remove_column:
 * @tb: a pointer to a struct libscols_table instance
 * @cl: a pointer to a struct libscols_column instance
 *
 * Removes @cl from @tb.
 *
 * Returns: 0, a negative number in case of an error.
 */
int scols_table_remove_column(struct libscols_table *tb,
			      struct libscols_column *cl)
{
	if (!tb || !cl || !list_empty(&tb->tb_lines))
		return -EINVAL;

	if (cl->flags & SCOLS_FL_TREE)
		tb->ntreecols--;

	DBG(TAB, ul_debugobj(tb, "remove column"));
	list_del_init(&cl->cl_columns);
	tb->ncols--;
	cl->table = NULL;
	scols_unref_column(cl);
	return 0;
}

/**
 * scols_table_remove_columns:
 * @tb: a pointer to a struct libscols_table instance
 *
 * Removes all of @tb's columns.
 *
 * Returns: 0, a negative number in case of an error.
 */
int scols_table_remove_columns(struct libscols_table *tb)
{
	if (!tb || !list_empty(&tb->tb_lines))
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "remove all columns"));
	while (!list_empty(&tb->tb_columns)) {
		struct libscols_column *cl = list_entry(tb->tb_columns.next,
					struct libscols_column, cl_columns);
		scols_table_remove_column(tb, cl);
	}
	return 0;
}

/**
 * scols_table_move_column:
 * @tb: table
 * @pre: column before the column
 * @cl: column to move
 *
 * Move the @cl behind @pre. If the @pre is NULL then the @col is the first
 * column in the table.
 *
 * Since: 2.30
 *
 * Returns: 0, a negative number in case of an error.
 */
int scols_table_move_column(struct libscols_table *tb,
			    struct libscols_column *pre,
			    struct libscols_column *cl)
{
	struct list_head *head;
	struct libscols_iter itr;
	struct libscols_column *p;
	struct libscols_line *ln;
	size_t n = 0, oldseq;

	if (!tb || !cl)
		return -EINVAL;

	if (pre && pre->seqnum + 1 == cl->seqnum)
		return 0;
	if (pre == NULL && cl->seqnum == 0)
		return 0;

	DBG(TAB, ul_debugobj(tb, "move column %zu behind %zu",
				cl->seqnum, pre? pre->seqnum : 0));

	list_del_init(&cl->cl_columns);		/* remove from old position */

	head = pre ? &pre->cl_columns : &tb->tb_columns;
	list_add(&cl->cl_columns, head);	/* add to the new place */

	oldseq = cl->seqnum;

	/* fix seq. numbers */
	scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
	while (scols_table_next_column(tb, &itr, &p) == 0)
		p->seqnum = n++;

	/* move data in lines */
	scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
	while (scols_table_next_line(tb, &itr, &ln) == 0)
		scols_line_move_cells(ln, cl->seqnum, oldseq);
	return 0;
}

/**
 * scols_table_new_column:
 * @tb: table
 * @name: column header
 * @whint: column width hint (absolute width: N > 1; relative width: 0 < N < 1)
 * @flags: flags integer
 *
 * This is shortcut for
 *
 *   cl = scols_new_column();
 *   scols_column_set_....(cl, ...);
 *   scols_table_add_column(tb, cl);
 *
 * The column width is possible to define by:
 *
 *  @whint: 0 < N < 1  : relative width, percent of terminal width
 *
 *  @whint: N >= 1     : absolute width, empty column will be truncated to
 *                     the column header width if no specified STRICTWIDTH flag
 *
 * Note that if table has disabled "maxout" flag (disabled by default) than
 * relative width is used as a hint only. It's possible that column will be
 * narrow if the specified size is too large for column data.
 *
 *
 * If the width of all columns is greater than terminal width then library
 * tries to reduce width of the individual columns. It's done in three stages:
 *
 * #1 reduce columns with SCOLS_FL_TRUNC flag and with relative width if the
 *    width is greater than width defined by @whint (@whint * terminal_width)
 *
 * #2 reduce all columns with SCOLS_FL_TRUNC flag
 *
 * #3 reduce all columns with relative width
 *
 * The next stage is always used if the previous stage is unsuccessful. Note
 * that SCOLS_FL_WRAP is interpreted as SCOLS_FL_TRUNC when calculate column
 * width (if custom wrap function is not specified), but the final text is not
 * truncated, but wrapped to multi-line cell.
 *
 *
 * The column is necessary to address by sequential number. The first defined
 * column has the colnum = 0. For example:
 *
 *	scols_table_new_column(tab, "FOO", 0.5, 0);		// colnum = 0
 *	scols_table_new_column(tab, "BAR", 0.5, 0);		// colnum = 1
 *      .
 *      .
 *	scols_line_get_cell(line, 0);				// FOO column
 *	scols_line_get_cell(line, 1);				// BAR column
 *
 * Returns: newly allocated column
 */
struct libscols_column *scols_table_new_column(struct libscols_table *tb,
					       const char *name,
					       double whint,
					       int flags)
{
	struct libscols_column *cl;
	struct libscols_cell *hr;

	if (!tb)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "new column name=%s, whint=%g, flags=%d",
				name, whint, flags));
	cl = scols_new_column();
	if (!cl)
		return NULL;

	/* set column name */
	hr = scols_column_get_header(cl);
	if (!hr)
		goto err;
	if (scols_cell_set_data(hr, name))
		goto err;

	scols_column_set_whint(cl, whint);
	scols_column_set_flags(cl, flags);

	if (scols_table_add_column(tb, cl))	/* this increments column ref-counter */
		goto err;

	scols_unref_column(cl);
	return cl;
err:
	scols_unref_column(cl);
	return NULL;
}

/**
 * scols_table_next_column:
 * @tb: a pointer to a struct libscols_table instance
 * @itr: a pointer to a struct libscols_iter instance
 * @cl: a pointer to a pointer to a struct libscols_column instance
 *
 * Returns the next column of @tb via @cl.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_table_next_column(struct libscols_table *tb,
			    struct libscols_iter *itr,
			    struct libscols_column **cl)
{
	int rc = 1;

	if (!tb || !itr || !cl)
		return -EINVAL;
	*cl = NULL;

	if (!itr->head)
		SCOLS_ITER_INIT(itr, &tb->tb_columns);
	if (itr->p != itr->head) {
		SCOLS_ITER_ITERATE(itr, *cl, struct libscols_column, cl_columns);
		rc = 0;
	}

	return rc;
}

/**
 * scols_table_get_ncols:
 * @tb: table
 *
 * Returns: the ncols table member.
 */
size_t scols_table_get_ncols(const struct libscols_table *tb)
{
	return tb->ncols;
}

/**
 * scols_table_get_nlines:
 * @tb: table
 *
 * Returns: the nlines table member.
 */
size_t scols_table_get_nlines(const struct libscols_table *tb)
{
	return tb->nlines;
}

/**
 * scols_table_set_stream:
 * @tb: table
 * @stream: output stream
 *
 * Sets the output stream for table @tb.
 *
 * Returns: 0, a negative number in case of an error.
 */
int scols_table_set_stream(struct libscols_table *tb, FILE *stream)
{
	assert(tb);
	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "setting alternative stream"));
	tb->out = stream;
	return 0;
}

/**
 * scols_table_get_stream:
 * @tb: table
 *
 * Gets the output stream for table @tb.
 *
 * Returns: stream pointer, NULL in case of an error or an unset stream.
 */
FILE *scols_table_get_stream(const struct libscols_table *tb)
{
	return tb->out;
}

/**
 * scols_table_reduce_termwidth:
 * @tb: table
 * @reduce: width
 *
 * If necessary then libsmartcols use all terminal width, the @reduce setting
 * provides extra space (for example for borders in ncurses applications).
 *
 * The @reduce must be smaller than terminal width, otherwise it's silently
 * ignored. The reduction is not applied when STDOUT_FILENO is not terminal.
 *
 * Note that after output initialization (scols_table_print_* calls) the width
 * will be reduced, this behavior affects subsequenced scols_table_get_termwidth()
 * calls.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_table_reduce_termwidth(struct libscols_table *tb, size_t reduce)
{
	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "reduce terminal width: %zu", reduce));
	tb->termreduce = reduce;
	return 0;
}

/**
 * scols_table_get_column:
 * @tb: table
 * @n: number of column (0..N)
 *
 * Returns: pointer to column or NULL
 */
struct libscols_column *scols_table_get_column(struct libscols_table *tb,
					       size_t n)
{
	struct libscols_iter itr;
	struct libscols_column *cl;

	if (!tb)
		return NULL;
	if (n >= tb->ncols)
		return NULL;

	scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
	while (scols_table_next_column(tb, &itr, &cl) == 0) {
		if (cl->seqnum == n)
			return cl;
	}
	return NULL;
}

/**
 * scols_table_add_line:
 * @tb: table
 * @ln: line
 *
 * Note that this function calls scols_line_alloc_cells() if number
 * of the cells in the line is too small for @tb.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_table_add_line(struct libscols_table *tb, struct libscols_line *ln)
{
	if (!tb || !ln || tb->ncols == 0)
		return -EINVAL;

	if (tb->ncols > ln->ncells) {
		int rc = scols_line_alloc_cells(ln, tb->ncols);
		if (rc)
			return rc;
	}

	DBG(TAB, ul_debugobj(tb, "add line"));
	list_add_tail(&ln->ln_lines, &tb->tb_lines);
	ln->seqnum = tb->nlines++;
	scols_ref_line(ln);
	return 0;
}

/**
 * scols_table_remove_line:
 * @tb: table
 * @ln: line
 *
 * Note that this function does not destroy the parent<->child relationship between lines.
 * You have to call scols_line_remove_child()
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_table_remove_line(struct libscols_table *tb,
			    struct libscols_line *ln)
{
	if (!tb || !ln)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "remove line"));
	list_del_init(&ln->ln_lines);
	tb->nlines--;
	scols_unref_line(ln);
	return 0;
}

/**
 * scols_table_remove_lines:
 * @tb: table
 *
 * This empties the table and also destroys all the parent<->child relationships.
 */
void scols_table_remove_lines(struct libscols_table *tb)
{
	if (!tb)
		return;

	DBG(TAB, ul_debugobj(tb, "remove all lines"));
	while (!list_empty(&tb->tb_lines)) {
		struct libscols_line *ln = list_entry(tb->tb_lines.next,
						struct libscols_line, ln_lines);
		if (ln->parent)
			scols_line_remove_child(ln->parent, ln);
		scols_table_remove_line(tb, ln);
	}
}

/**
 * scols_table_next_line:
 * @tb: a pointer to a struct libscols_table instance
 * @itr: a pointer to a struct libscols_iter instance
 * @ln: a pointer to a pointer to a struct libscols_line instance
 *
 * Finds the next line and returns a pointer to it via @ln.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_table_next_line(struct libscols_table *tb,
			  struct libscols_iter *itr,
			  struct libscols_line **ln)
{
	int rc = 1;

	if (!tb || !itr || !ln)
		return -EINVAL;
	*ln = NULL;

	if (!itr->head)
		SCOLS_ITER_INIT(itr, &tb->tb_lines);
	if (itr->p != itr->head) {
		SCOLS_ITER_ITERATE(itr, *ln, struct libscols_line, ln_lines);
		rc = 0;
	}

	return rc;
}

/**
 * scols_table_new_line:
 * @tb: table
 * @parent: parental line or NULL
 *
 * This is shortcut for
 *
 *   ln = scols_new_line();
 *   scols_table_add_line(tb, ln);
 *   scols_line_add_child(parent, ln);
 *
 *
 * Returns: newly allocate line
 */
struct libscols_line *scols_table_new_line(struct libscols_table *tb,
					   struct libscols_line *parent)
{
	struct libscols_line *ln;

	if (!tb || !tb->ncols)
		return NULL;

	ln = scols_new_line();
	if (!ln)
		return NULL;

	if (scols_table_add_line(tb, ln))
		goto err;
	if (parent)
		scols_line_add_child(parent, ln);

	scols_unref_line(ln);	/* ref-counter incremented by scols_table_add_line() */
	return ln;
err:
	scols_unref_line(ln);
	return NULL;
}

/**
 * scols_table_get_line:
 * @tb: table
 * @n: column number (0..N)
 *
 * Returns: a line or NULL
 */
struct libscols_line *scols_table_get_line(struct libscols_table *tb,
					   size_t n)
{
	struct libscols_iter itr;
	struct libscols_line *ln;

	if (!tb)
		return NULL;
	if (n >= tb->nlines)
		return NULL;

	scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
	while (scols_table_next_line(tb, &itr, &ln) == 0) {
		if (ln->seqnum == n)
			return ln;
	}
	return NULL;
}

/**
 * scols_copy_table:
 * @tb: table
 *
 * Creates a new independent table copy, except struct libscols_symbols that
 * are shared between the tables.
 *
 * Returns: a newly allocated copy of @tb
 */
struct libscols_table *scols_copy_table(struct libscols_table *tb)
{
	struct libscols_table *ret;
	struct libscols_line *ln;
	struct libscols_column *cl;
	struct libscols_iter itr;

	if (!tb)
		return NULL;
	ret = scols_new_table();
	if (!ret)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "copy"));

	if (tb->symbols)
		scols_table_set_symbols(ret, tb->symbols);

	/* columns */
	scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
	while (scols_table_next_column(tb, &itr, &cl) == 0) {
		cl = scols_copy_column(cl);
		if (!cl)
			goto err;
		if (scols_table_add_column(ret, cl))
			goto err;
		scols_unref_column(cl);
	}

	/* lines */
	scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
	while (scols_table_next_line(tb, &itr, &ln) == 0) {
		struct libscols_line *newln = scols_copy_line(ln);
		if (!newln)
			goto err;
		if (scols_table_add_line(ret, newln))
			goto err;
		if (ln->parent) {
			struct libscols_line *p =
				scols_table_get_line(ret, ln->parent->seqnum);
			if (p)
				scols_line_add_child(p, newln);
		}
		scols_unref_line(newln);
	}

	/* separators */
	if (scols_table_set_column_separator(ret, tb->colsep) ||
	    scols_table_set_line_separator(ret, tb->linesep))
		goto err;

	return ret;
err:
	scols_unref_table(ret);
	return NULL;
}

/**
 * scols_table_set_default_symbols:
 * @tb: table
 *
 * The library check the current environment to select ASCII or UTF8 symbols.
 * This default behavior could be controlled by scols_table_enable_ascii().
 *
 * Use scols_table_set_symbols() to unset symbols or use your own setting.
 *
 * Returns: 0, a negative value in case of an error.
 *
 * Since: 2.29
 */
int scols_table_set_default_symbols(struct libscols_table *tb)
{
	struct libscols_symbols *sy;
	int rc;

	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "setting default symbols"));

	sy = scols_new_symbols();
	if (!sy)
		return -ENOMEM;

#if defined(HAVE_WIDECHAR)
	if (!scols_table_is_ascii(tb) &&
	    !strcmp(nl_langinfo(CODESET), "UTF-8")) {
		scols_symbols_set_branch(sy, UTF_VR UTF_H);
		scols_symbols_set_vertical(sy, UTF_V " ");
		scols_symbols_set_right(sy, UTF_UR UTF_H);
	} else
#endif
	{
		scols_symbols_set_branch(sy, "|-");
		scols_symbols_set_vertical(sy, "| ");
		scols_symbols_set_right(sy, "`-");
	}
	scols_symbols_set_title_padding(sy, " ");
	scols_symbols_set_cell_padding(sy, " ");

	rc = scols_table_set_symbols(tb, sy);
	scols_unref_symbols(sy);
	return rc;
}


/**
 * scols_table_set_symbols:
 * @tb: table
 * @sy: symbols or NULL
 *
 * Add a reference to @sy from the table. The symbols are used by library to
 * draw tree output. If no symbols are used for the table then library creates
 * default temporary symbols to draw output by scols_table_set_default_symbols().
 *
 * If @sy is NULL then remove reference from the currently used symbols.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_table_set_symbols(struct libscols_table *tb,
			    struct libscols_symbols *sy)
{
	if (!tb)
		return -EINVAL;

	/* remove old */
	if (tb->symbols) {
		DBG(TAB, ul_debugobj(tb, "remove symbols reference"));
		scols_unref_symbols(tb->symbols);
		tb->symbols = NULL;
	}

	/* set new */
	if (sy) {					/* ref user defined */
		DBG(TAB, ul_debugobj(tb, "set symbols"));
		tb->symbols = sy;
		scols_ref_symbols(sy);
	}
	return 0;
}

/**
 * scols_table_get_symbols:
 * @tb: table
 *
 * Returns: pointer to symbols table.
 *
 * Since: 2.29
 */
struct libscols_symbols *scols_table_get_symbols(const struct libscols_table *tb)
{
	return tb->symbols;
}

/**
 * scols_table_enable_nolinesep:
 * @tb: table
 * @enable: 1 or 0
 *
 * Enable/disable line separator printing. This is useful if you want to
 * re-printing the same line more than once (e.g. progress bar). Don't use it
 * if you're not sure.
 *
 * Note that for the last line in the table the separator is disabled at all.
 * The library differentiate between table terminator and line terminator
 * (although for standard output \n byte is used in both cases).
 *
 * Returns: 0 on success, negative number in case of an error.
 */
int scols_table_enable_nolinesep(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "nolinesep: %s", enable ? "ENABLE" : "DISABLE"));
	tb->no_linesep = enable ? 1 : 0;
	return 0;
}

/**
 * scols_table_is_nolinesep:
 * @tb: a pointer to a struct libscols_table instance
 *
 * Returns: 1 if line separator printing is disabled.
 *
 * Since: 2.29
 */
int scols_table_is_nolinesep(const struct libscols_table *tb)
{
	return tb->no_linesep;
}

/**
 * scols_table_enable_colors:
 * @tb: table
 * @enable: 1 or 0
 *
 * Enable/disable colors.
 *
 * Returns: 0 on success, negative number in case of an error.
 */
int scols_table_enable_colors(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "colors: %s", enable ? "ENABLE" : "DISABLE"));
	tb->colors_wanted = enable;
	return 0;
}

/**
 * scols_table_enable_raw:
 * @tb: table
 * @enable: 1 or 0
 *
 * Enable/disable raw output format. The parsable output formats
 * (export, raw, JSON, ...) are mutually exclusive.
 *
 * Returns: 0 on success, negative number in case of an error.
 */
int scols_table_enable_raw(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "raw: %s", enable ? "ENABLE" : "DISABLE"));
	if (enable)
		tb->format = SCOLS_FMT_RAW;
	else if (tb->format == SCOLS_FMT_RAW)
		tb->format = 0;
	return 0;
}

/**
 * scols_table_enable_json:
 * @tb: table
 * @enable: 1 or 0
 *
 * Enable/disable JSON output format. The parsable output formats
 * (export, raw, JSON, ...) are mutually exclusive.
 *
 * Returns: 0 on success, negative number in case of an error.
 *
 * Since: 2.27
 */
int scols_table_enable_json(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "json: %s", enable ? "ENABLE" : "DISABLE"));
	if (enable)
		tb->format = SCOLS_FMT_JSON;
	else if (tb->format == SCOLS_FMT_JSON)
		tb->format = 0;
	return 0;
}

/**
 * scols_table_enable_export:
 * @tb: table
 * @enable: 1 or 0
 *
 * Enable/disable export output format (COLUMNAME="value" ...).
 * The parsable output formats (export and raw) are mutually exclusive.
 *
 * Returns: 0 on success, negative number in case of an error.
 */
int scols_table_enable_export(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "export: %s", enable ? "ENABLE" : "DISABLE"));
	if (enable)
		tb->format = SCOLS_FMT_EXPORT;
	else if (tb->format == SCOLS_FMT_EXPORT)
		tb->format = 0;
	return 0;
}

/**
 * scols_table_enable_ascii:
 * @tb: table
 * @enable: 1 or 0
 *
 * The ASCII-only output is relevant for tree-like outputs. The library
 * checks if the current environment is UTF8 compatible by default. This
 * function overrides this check and force the library to use ASCII chars
 * for the tree.
 *
 * If a custom libcols_symbols are specified (see scols_table_set_symbols()
 * then ASCII flag setting is ignored.
 *
 * Returns: 0 on success, negative number in case of an error.
 */
int scols_table_enable_ascii(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "ascii: %s", enable ? "ENABLE" : "DISABLE"));
	tb->ascii = enable ? 1 : 0;
	return 0;
}

/**
 * scols_table_enable_noheadings:
 * @tb: table
 * @enable: 1 or 0
 *
 * Enable/disable header line.
 *
 * Returns: 0 on success, negative number in case of an error.
 */
int scols_table_enable_noheadings(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;
	DBG(TAB, ul_debugobj(tb, "noheading: %s", enable ? "ENABLE" : "DISABLE"));
	tb->no_headings = enable ? 1 : 0;
	return 0;
}

/**
 * scols_table_enable_header_repeat:
 * @tb: table
 * @enable: 1 or 0
 *
 * Enable/disable header line repeat. The header line is printed only once by
 * default.  Note that the flag will be silently ignored and disabled if the
 * output is not on terminal or output format is JSON, raw, etc.
 *
 * Returns: 0 on success, negative number in case of an error.
 *
 * Since: 2.31
 */
int scols_table_enable_header_repeat(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;
	DBG(TAB, ul_debugobj(tb, "header-repeat: %s", enable ? "ENABLE" : "DISABLE"));
	tb->header_repeat = enable ? 1 : 0;
	return 0;
}

/**
 * scols_table_enable_maxout:
 * @tb: table
 * @enable: 1 or 0
 *
 * The extra space after last column is ignored by default. The output
 * maximization use the extra space for all columns.
 *
 * Returns: 0 on success, negative number in case of an error.
 */
int scols_table_enable_maxout(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;
	DBG(TAB, ul_debugobj(tb, "maxout: %s", enable ? "ENABLE" : "DISABLE"));
	tb->maxout = enable ? 1 : 0;
	return 0;
}

/**
 * scols_table_enable_nowrap:
 * @tb: table
 * @enable: 1 or 0
 *
 * Never continue on next line, remove last column(s) when too large, truncate last column.
 *
 * Returns: 0 on success, negative number in case of an error.
 *
 * Since: 2.28
 */
int scols_table_enable_nowrap(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;
	DBG(TAB, ul_debugobj(tb, "nowrap: %s", enable ? "ENABLE" : "DISABLE"));
	tb->no_wrap = enable ? 1 : 0;
	return 0;
}

/**
 * scols_table_is_nowrap:
 * @tb: a pointer to a struct libscols_table instance
 *
 * Returns: 1 if nowrap is enabled.
 *
 * Since: 2.29
 */
int scols_table_is_nowrap(const struct libscols_table *tb)
{
	return tb->no_wrap;
}

/**
 * scols_table_enable_noencoding:
 * @tb: table
 * @enable: 1 or 0
 *
 * The library encode non-printable and control chars by \xHEX by default.
 *
 * Returns: 0 on success, negative number in case of an error.
 *
 * Since: 2.31
 */
int scols_table_enable_noencoding(struct libscols_table *tb, int enable)
{
	if (!tb)
		return -EINVAL;
	DBG(TAB, ul_debugobj(tb, "encoding: %s", enable ? "ENABLE" : "DISABLE"));
	tb->no_encode = enable ? 1 : 0;
	return 0;
}

/**
 * scols_table_is_noencoding:
 * @tb: a pointer to a struct libscols_table instance
 *
 * Returns: 1 if encoding is disabled.
 *
 * Since: 2.31
 */
int scols_table_is_noencoding(const struct libscols_table *tb)
{
	return tb->no_encode;
}

/**
 * scols_table_colors_wanted:
 * @tb: table
 *
 * Returns: 1 if colors are enabled.
 */
int scols_table_colors_wanted(const struct libscols_table *tb)
{
	return tb->colors_wanted;
}

/**
 * scols_table_is_empty:
 * @tb: table
 *
 * Returns: 1 if the table is empty.
 */
int scols_table_is_empty(const struct libscols_table *tb)
{
	return !tb->nlines;
}

/**
 * scols_table_is_ascii:
 * @tb: table
 *
 * Returns: 1 if ASCII tree is enabled.
 */
int scols_table_is_ascii(const struct libscols_table *tb)
{
	return tb->ascii;
}

/**
 * scols_table_is_noheadings:
 * @tb: table
 *
 * Returns: 1 if header output is disabled.
 */
int scols_table_is_noheadings(const struct libscols_table *tb)
{
	return tb->no_headings;
}

/**
 * scols_table_is_header_repeat
 * @tb: table
 *
 * Returns: 1 if header repeat is enabled.
 *
 * Since: 2.31
 */
int scols_table_is_header_repeat(const struct libscols_table *tb)
{
	return tb->header_repeat;
}

/**
 * scols_table_is_export:
 * @tb: table
 *
 * Returns: 1 if export output format is enabled.
 */
int scols_table_is_export(const struct libscols_table *tb)
{
	return tb->format == SCOLS_FMT_EXPORT;
}

/**
 * scols_table_is_raw:
 * @tb: table
 *
 * Returns: 1 if raw output format is enabled.
 */
int scols_table_is_raw(const struct libscols_table *tb)
{
	return tb->format == SCOLS_FMT_RAW;
}

/**
 * scols_table_is_json:
 * @tb: table
 *
 * Returns: 1 if JSON output format is enabled.
 *
 * Since: 2.27
 */
int scols_table_is_json(const struct libscols_table *tb)
{
	return tb->format == SCOLS_FMT_JSON;
}

/**
 * scols_table_is_maxout
 * @tb: table
 *
 * Returns: 1 if output maximization is enabled or 0
 */
int scols_table_is_maxout(const struct libscols_table *tb)
{
	return tb->maxout;
}

/**
 * scols_table_is_tree:
 * @tb: table
 *
 * Returns: returns 1 tree-like output is expected.
 */
int scols_table_is_tree(const struct libscols_table *tb)
{
	return tb->ntreecols > 0;
}

/**
 * scols_table_set_column_separator:
 * @tb: table
 * @sep: separator
 *
 * Sets the column separator of @tb to @sep.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_table_set_column_separator(struct libscols_table *tb, const char *sep)
{
	return strdup_to_struct_member(tb, colsep, sep);
}

/**
 * scols_table_set_line_separator:
 * @tb: table
 * @sep: separator
 *
 * Sets the line separator of @tb to @sep.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_table_set_line_separator(struct libscols_table *tb, const char *sep)
{
	return strdup_to_struct_member(tb, linesep, sep);
}

/**
 * scols_table_get_column_separator:
 * @tb: table
 *
 * Returns: @tb column separator, NULL in case of an error
 */
const char *scols_table_get_column_separator(const struct libscols_table *tb)
{
	return tb->colsep;
}

/**
 * scols_table_get_line_separator:
 * @tb: table
 *
 * Returns: @tb line separator, NULL in case of an error
 */
const char *scols_table_get_line_separator(const struct libscols_table *tb)
{
	return tb->linesep;
}
/* for lines in the struct libscols_line->ln_lines list */
static int cells_cmp_wrapper_lines(struct list_head *a, struct list_head *b, void *data)
{
	struct libscols_column *cl = (struct libscols_column *) data;
	struct libscols_line *ra, *rb;
	struct libscols_cell *ca, *cb;

	assert(a);
	assert(b);
	assert(cl);

	ra = list_entry(a, struct libscols_line, ln_lines);
	rb = list_entry(b, struct libscols_line, ln_lines);
	ca = scols_line_get_cell(ra, cl->seqnum);
	cb = scols_line_get_cell(rb, cl->seqnum);

	return cl->cmpfunc(ca, cb, cl->cmpfunc_data);
}

/* for lines in the struct libscols_line->ln_children list */
static int cells_cmp_wrapper_children(struct list_head *a, struct list_head *b, void *data)
{
	struct libscols_column *cl = (struct libscols_column *) data;
	struct libscols_line *ra, *rb;
	struct libscols_cell *ca, *cb;

	assert(a);
	assert(b);
	assert(cl);

	ra = list_entry(a, struct libscols_line, ln_children);
	rb = list_entry(b, struct libscols_line, ln_children);
	ca = scols_line_get_cell(ra, cl->seqnum);
	cb = scols_line_get_cell(rb, cl->seqnum);

	return cl->cmpfunc(ca, cb, cl->cmpfunc_data);
}


static int sort_line_children(struct libscols_line *ln, struct libscols_column *cl)
{
	struct list_head *p;

	if (list_empty(&ln->ln_branch))
		return 0;

	list_for_each(p, &ln->ln_branch) {
		struct libscols_line *chld =
				list_entry(p, struct libscols_line, ln_children);
		sort_line_children(chld, cl);
	}

	list_sort(&ln->ln_branch, cells_cmp_wrapper_children, cl);
	return 0;
}

/**
 * scols_sort_table:
 * @tb: table
 * @cl: order by this column
 *
 * Orders the table by the column. See also scols_column_set_cmpfunc(). If the
 * tree output is enabled then children in the tree are recursively sorted too.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl)
{
	if (!tb || !cl || !cl->cmpfunc)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "sorting table"));
	list_sort(&tb->tb_lines, cells_cmp_wrapper_lines, cl);

	if (scols_table_is_tree(tb)) {
		struct libscols_line *ln;
		struct libscols_iter itr;

		scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
		while (scols_table_next_line(tb, &itr, &ln) == 0)
			sort_line_children(ln, cl);
	}

	return 0;
}

static struct libscols_line *move_line_and_children(struct libscols_line *ln, struct libscols_line *pre)
{
	if (pre) {
		list_del_init(&ln->ln_lines);			/* remove from old position */
	        list_add(&ln->ln_lines, &pre->ln_lines);        /* add to the new place (behind @pre) */
	}
	pre = ln;

	if (!list_empty(&ln->ln_branch)) {
		struct list_head *p;

		list_for_each(p, &ln->ln_branch) {
			struct libscols_line *chld =
					list_entry(p, struct libscols_line, ln_children);
			pre = move_line_and_children(chld, pre);
		}
	}

	return pre;
}

/**
 * scols_sort_table_by_tree:
 * @tb: table
 *
 * Reorders lines in the table by parent->child relation. Note that order of
 * the lines in the table is independent on the tree hierarchy.
 *
 * Since: 2.30
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_sort_table_by_tree(struct libscols_table *tb)
{
	struct libscols_line *ln;
	struct libscols_iter itr;

	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "sorting table by tree"));

	scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
	while (scols_table_next_line(tb, &itr, &ln) == 0) {
		if (ln->parent)
			continue;

		move_line_and_children(ln, NULL);
	}

	return 0;
}


/**
 * scols_table_set_termforce:
 * @tb: table
 * @force: SCOLS_TERMFORCE_{NEVER,ALWAYS,AUTO}
 *
 * Forces library to use stdout as terminal, non-terminal or use automatic
 * detection (default).
 *
 * Returns: 0, a negative value in case of an error.
 *
 * Since: 2.29
 */
int scols_table_set_termforce(struct libscols_table *tb, int force)
{
	if (!tb)
		return -EINVAL;
	tb->termforce = force;
	return 0;
}

/**
 * scols_table_get_termforce:
 * @tb: table
 *
 * Returns: SCOLS_TERMFORCE_{NEVER,ALWAYS,AUTO} or a negative value in case of an error.
 *
 * Since: 2.29
 */
int scols_table_get_termforce(const struct libscols_table *tb)
{
	return tb->termforce;
}

/**
 * scols_table_set_termwidth
 * @tb: table
 * @width: terminal width
 *
 * The library automatically detects terminal width or defaults to 80 chars if
 * detections is unsuccessful. This function override this behaviour.
 *
 * Returns: 0, a negative value in case of an error.
 *
 * Since: 2.29
 */
int scols_table_set_termwidth(struct libscols_table *tb, size_t width)
{
	DBG(TAB, ul_debugobj(tb, "set terminatl width: %zu", width));
	tb->termwidth = width;
	return 0;
}

/**
 * scols_table_get_termwidth
 * @tb: table
 *
 * Returns: terminal width.
 */
size_t scols_table_get_termwidth(const struct libscols_table *tb)
{
	return tb->termwidth;
}

/**
 * scols_table_set_termheight
 * @tb: table
 * @height: terminal height (number of lines)
 *
 * The library automatically detects terminal height or defaults to 24 lines if
 * detections is unsuccessful. This function override this behaviour.
 *
 * Returns: 0, a negative value in case of an error.
 *
 * Since: 2.31
 */
int scols_table_set_termheight(struct libscols_table *tb, size_t height)
{
	DBG(TAB, ul_debugobj(tb, "set terminatl height: %zu", height));
	tb->termheight = height;
	return 0;
}

/**
 * scols_table_get_termheight
 * @tb: table
 *
 * Returns: terminal height (number of lines).
 *
 * Since: 2.31
 */
size_t scols_table_get_termheight(const struct libscols_table *tb)
{
	return tb->termheight;
}
