// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

// This module is a Table Writer  API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems

// Create & Generate text based table
package tablewriter

import (
	"bytes"
	"fmt"
	"io"
	"regexp"
	"strings"
)

const (
	MAX_ROW_WIDTH = 30
)

const (
	CENTER  = "+"
	ROW     = "-"
	COLUMN  = "|"
	SPACE   = " "
	NEWLINE = "\n"
)

const (
	ALIGN_DEFAULT = iota
	ALIGN_CENTER
	ALIGN_RIGHT
	ALIGN_LEFT
)

var (
	decimal = regexp.MustCompile(`^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$`)
	percent = regexp.MustCompile(`^-?\d+\.?\d*$%$`)
)

type Border struct {
	Left   bool
	Right  bool
	Top    bool
	Bottom bool
}

type Table struct {
	out            io.Writer
	rows           [][]string
	lines          [][][]string
	cs             map[int]int
	rs             map[int]int
	headers        [][]string
	footers        [][]string
	caption        bool
	captionText    string
	autoFmt        bool
	autoWrap       bool
	reflowText     bool
	mW             int
	pCenter        string
	pRow           string
	pColumn        string
	tColumn        int
	tRow           int
	hAlign         int
	fAlign         int
	align          int
	newLine        string
	rowLine        bool
	autoMergeCells bool
	noWhiteSpace   bool
	tablePadding   string
	hdrLine        bool
	borders        Border
	colSize        int
	headerParams   []string
	columnsParams  []string
	footerParams   []string
	columnsAlign   []int
}

// Start New Table
// Take io.Writer Directly
func NewWriter(writer io.Writer) *Table {
	t := &Table{
		out:           writer,
		rows:          [][]string{},
		lines:         [][][]string{},
		cs:            make(map[int]int),
		rs:            make(map[int]int),
		headers:       [][]string{},
		footers:       [][]string{},
		caption:       false,
		captionText:   "Table caption.",
		autoFmt:       true,
		autoWrap:      true,
		reflowText:    true,
		mW:            MAX_ROW_WIDTH,
		pCenter:       CENTER,
		pRow:          ROW,
		pColumn:       COLUMN,
		tColumn:       -1,
		tRow:          -1,
		hAlign:        ALIGN_DEFAULT,
		fAlign:        ALIGN_DEFAULT,
		align:         ALIGN_DEFAULT,
		newLine:       NEWLINE,
		rowLine:       false,
		hdrLine:       true,
		borders:       Border{Left: true, Right: true, Bottom: true, Top: true},
		colSize:       -1,
		headerParams:  []string{},
		columnsParams: []string{},
		footerParams:  []string{},
		columnsAlign:  []int{}}
	return t
}

// Render table output
func (t *Table) Render() {
	if t.borders.Top {
		t.printLine(true)
	}
	t.printHeading()
	if t.autoMergeCells {
		t.printRowsMergeCells()
	} else {
		t.printRows()
	}
	if !t.rowLine && t.borders.Bottom {
		t.printLine(true)
	}
	t.printFooter()

	if t.caption {
		t.printCaption()
	}
}

const (
	headerRowIdx = -1
	footerRowIdx = -2
)

// Set table header
func (t *Table) SetHeader(keys []string) {
	t.colSize = len(keys)
	for i, v := range keys {
		lines := t.parseDimension(v, i, headerRowIdx)
		t.headers = append(t.headers, lines)
	}
}

// Set table Footer
func (t *Table) SetFooter(keys []string) {
	//t.colSize = len(keys)
	for i, v := range keys {
		lines := t.parseDimension(v, i, footerRowIdx)
		t.footers = append(t.footers, lines)
	}
}

// Set table Caption
func (t *Table) SetCaption(caption bool, captionText ...string) {
	t.caption = caption
	if len(captionText) == 1 {
		t.captionText = captionText[0]
	}
}

// Turn header autoformatting on/off. Default is on (true).
func (t *Table) SetAutoFormatHeaders(auto bool) {
	t.autoFmt = auto
}

// Turn automatic multiline text adjustment on/off. Default is on (true).
func (t *Table) SetAutoWrapText(auto bool) {
	t.autoWrap = auto
}

// Turn automatic reflowing of multiline text when rewrapping. Default is on (true).
func (t *Table) SetReflowDuringAutoWrap(auto bool) {
	t.reflowText = auto
}

// Set the Default column width
func (t *Table) SetColWidth(width int) {
	t.mW = width
}

// Set the minimal width for a column
func (t *Table) SetColMinWidth(column int, width int) {
	t.cs[column] = width
}

// Set the Column Separator
func (t *Table) SetColumnSeparator(sep string) {
	t.pColumn = sep
}

// Set the Row Separator
func (t *Table) SetRowSeparator(sep string) {
	t.pRow = sep
}

// Set the center Separator
func (t *Table) SetCenterSeparator(sep string) {
	t.pCenter = sep
}

// Set Header Alignment
func (t *Table) SetHeaderAlignment(hAlign int) {
	t.hAlign = hAlign
}

// Set Footer Alignment
func (t *Table) SetFooterAlignment(fAlign int) {
	t.fAlign = fAlign
}

// Set Table Alignment
func (t *Table) SetAlignment(align int) {
	t.align = align
}

// Set No White Space
func (t *Table) SetNoWhiteSpace(allow bool) {
	t.noWhiteSpace = allow
}

// Set Table Padding
func (t *Table) SetTablePadding(padding string) {
	t.tablePadding = padding
}

func (t *Table) SetColumnAlignment(keys []int) {
	for _, v := range keys {
		switch v {
		case ALIGN_CENTER:
			break
		case ALIGN_LEFT:
			break
		case ALIGN_RIGHT:
			break
		default:
			v = ALIGN_DEFAULT
		}
		t.columnsAlign = append(t.columnsAlign, v)
	}
}

// Set New Line
func (t *Table) SetNewLine(nl string) {
	t.newLine = nl
}

// Set Header Line
// This would enable / disable a line after the header
func (t *Table) SetHeaderLine(line bool) {
	t.hdrLine = line
}

// Set Row Line
// This would enable / disable a line on each row of the table
func (t *Table) SetRowLine(line bool) {
	t.rowLine = line
}

// Set Auto Merge Cells
// This would enable / disable the merge of cells with identical values
func (t *Table) SetAutoMergeCells(auto bool) {
	t.autoMergeCells = auto
}

// Set Table Border
// This would enable / disable line around the table
func (t *Table) SetBorder(border bool) {
	t.SetBorders(Border{border, border, border, border})
}

func (t *Table) SetBorders(border Border) {
	t.borders = border
}

// Append row to table
func (t *Table) Append(row []string) {
	rowSize := len(t.headers)
	if rowSize > t.colSize {
		t.colSize = rowSize
	}

	n := len(t.lines)
	line := [][]string{}
	for i, v := range row {

		// Detect string  width
		// Detect String height
		// Break strings into words
		out := t.parseDimension(v, i, n)

		// Append broken words
		line = append(line, out)
	}
	t.lines = append(t.lines, line)
}

// Append row to table with color attributes
func (t *Table) Rich(row []string, colors []Colors) {
	rowSize := len(t.headers)
	if rowSize > t.colSize {
		t.colSize = rowSize
	}

	n := len(t.lines)
	line := [][]string{}
	for i, v := range row {

		// Detect string  width
		// Detect String height
		// Break strings into words
		out := t.parseDimension(v, i, n)

		if len(colors) > i {
			color := colors[i]
			out[0] = format(out[0], color)
		}

		// Append broken words
		line = append(line, out)
	}
	t.lines = append(t.lines, line)
}

// Allow Support for Bulk Append
// Eliminates repeated for loops
func (t *Table) AppendBulk(rows [][]string) {
	for _, row := range rows {
		t.Append(row)
	}
}

// NumLines to get the number of lines
func (t *Table) NumLines() int {
	return len(t.lines)
}

// Clear rows
func (t *Table) ClearRows() {
	t.lines = [][][]string{}
}

// Clear footer
func (t *Table) ClearFooter() {
	t.footers = [][]string{}
}

// Center based on position and border.
func (t *Table) center(i int) string {
	if i == -1 && !t.borders.Left {
		return t.pRow
	}

	if i == len(t.cs)-1 && !t.borders.Right {
		return t.pRow
	}

	return t.pCenter
}

// Print line based on row width
func (t *Table) printLine(nl bool) {
	fmt.Fprint(t.out, t.center(-1))
	for i := 0; i < len(t.cs); i++ {
		v := t.cs[i]
		fmt.Fprintf(t.out, "%s%s%s%s",
			t.pRow,
			strings.Repeat(string(t.pRow), v),
			t.pRow,
			t.center(i))
	}
	if nl {
		fmt.Fprint(t.out, t.newLine)
	}
}

// Print line based on row width with our without cell separator
func (t *Table) printLineOptionalCellSeparators(nl bool, displayCellSeparator []bool) {
	fmt.Fprint(t.out, t.pCenter)
	for i := 0; i < len(t.cs); i++ {
		v := t.cs[i]
		if i > len(displayCellSeparator) || displayCellSeparator[i] {
			// Display the cell separator
			fmt.Fprintf(t.out, "%s%s%s%s",
				t.pRow,
				strings.Repeat(string(t.pRow), v),
				t.pRow,
				t.pCenter)
		} else {
			// Don't display the cell separator for this cell
			fmt.Fprintf(t.out, "%s%s",
				strings.Repeat(" ", v+2),
				t.pCenter)
		}
	}
	if nl {
		fmt.Fprint(t.out, t.newLine)
	}
}

// Return the PadRight function if align is left, PadLeft if align is right,
// and Pad by default
func pad(align int) func(string, string, int) string {
	padFunc := Pad
	switch align {
	case ALIGN_LEFT:
		padFunc = PadRight
	case ALIGN_RIGHT:
		padFunc = PadLeft
	}
	return padFunc
}

// Print heading information
func (t *Table) printHeading() {
	// Check if headers is available
	if len(t.headers) < 1 {
		return
	}

	// Identify last column
	end := len(t.cs) - 1

	// Get pad function
	padFunc := pad(t.hAlign)

	// Checking for ANSI escape sequences for header
	is_esc_seq := false
	if len(t.headerParams) > 0 {
		is_esc_seq = true
	}

	// Maximum height.
	max := t.rs[headerRowIdx]

	// Print Heading
	for x := 0; x < max; x++ {
		// Check if border is set
		// Replace with space if not set
		if !t.noWhiteSpace {
			fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE))
		}

		for y := 0; y <= end; y++ {
			v := t.cs[y]
			h := ""

			if y < len(t.headers) && x < len(t.headers[y]) {
				h = t.headers[y][x]
			}
			if t.autoFmt {
				h = Title(h)
			}
			pad := ConditionString((y == end && !t.borders.Left), SPACE, t.pColumn)
			if t.noWhiteSpace {
				pad = ConditionString((y == end && !t.borders.Left), SPACE, t.tablePadding)
			}
			if is_esc_seq {
				if !t.noWhiteSpace {
					fmt.Fprintf(t.out, " %s %s",
						format(padFunc(h, SPACE, v),
							t.headerParams[y]), pad)
				} else {
					fmt.Fprintf(t.out, "%s %s",
						format(padFunc(h, SPACE, v),
							t.headerParams[y]), pad)
				}
			} else {
				if !t.noWhiteSpace {
					fmt.Fprintf(t.out, " %s %s",
						padFunc(h, SPACE, v),
						pad)
				} else {
					// the spaces between breaks the kube formatting
					fmt.Fprintf(t.out, "%s%s",
						padFunc(h, SPACE, v),
						pad)
				}
			}
		}
		// Next line
		fmt.Fprint(t.out, t.newLine)
	}
	if t.hdrLine {
		t.printLine(true)
	}
}

// Print heading information
func (t *Table) printFooter() {
	// Check if headers is available
	if len(t.footers) < 1 {
		return
	}

	// Only print line if border is not set
	if !t.borders.Bottom {
		t.printLine(true)
	}

	// Identify last column
	end := len(t.cs) - 1

	// Get pad function
	padFunc := pad(t.fAlign)

	// Checking for ANSI escape sequences for header
	is_esc_seq := false
	if len(t.footerParams) > 0 {
		is_esc_seq = true
	}

	// Maximum height.
	max := t.rs[footerRowIdx]

	// Print Footer
	erasePad := make([]bool, len(t.footers))
	for x := 0; x < max; x++ {
		// Check if border is set
		// Replace with space if not set
		fmt.Fprint(t.out, ConditionString(t.borders.Bottom, t.pColumn, SPACE))

		for y := 0; y <= end; y++ {
			v := t.cs[y]
			f := ""
			if y < len(t.footers) && x < len(t.footers[y]) {
				f = t.footers[y][x]
			}
			if t.autoFmt {
				f = Title(f)
			}
			pad := ConditionString((y == end && !t.borders.Top), SPACE, t.pColumn)

			if erasePad[y] || (x == 0 && len(f) == 0) {
				pad = SPACE
				erasePad[y] = true
			}

			if is_esc_seq {
				fmt.Fprintf(t.out, " %s %s",
					format(padFunc(f, SPACE, v),
						t.footerParams[y]), pad)
			} else {
				fmt.Fprintf(t.out, " %s %s",
					padFunc(f, SPACE, v),
					pad)
			}

			//fmt.Fprintf(t.out, " %s %s",
			//	padFunc(f, SPACE, v),
			//	pad)
		}
		// Next line
		fmt.Fprint(t.out, t.newLine)
		//t.printLine(true)
	}

	hasPrinted := false

	for i := 0; i <= end; i++ {
		v := t.cs[i]
		pad := t.pRow
		center := t.pCenter
		length := len(t.footers[i][0])

		if length > 0 {
			hasPrinted = true
		}

		// Set center to be space if length is 0
		if length == 0 && !t.borders.Right {
			center = SPACE
		}

		// Print first junction
		if i == 0 {
			if length > 0 && !t.borders.Left {
				center = t.pRow
			}
			fmt.Fprint(t.out, center)
		}

		// Pad With space of length is 0
		if length == 0 {
			pad = SPACE
		}
		// Ignore left space as it has printed before
		if hasPrinted || t.borders.Left {
			pad = t.pRow
			center = t.pCenter
		}

		// Change Center end position
		if center != SPACE {
			if i == end && !t.borders.Right {
				center = t.pRow
			}
		}

		// Change Center start position
		if center == SPACE {
			if i < end && len(t.footers[i+1][0]) != 0 {
				if !t.borders.Left {
					center = t.pRow
				} else {
					center = t.pCenter
				}
			}
		}

		// Print the footer
		fmt.Fprintf(t.out, "%s%s%s%s",
			pad,
			strings.Repeat(string(pad), v),
			pad,
			center)

	}

	fmt.Fprint(t.out, t.newLine)
}

// Print caption text
func (t Table) printCaption() {
	width := t.getTableWidth()
	paragraph, _ := WrapString(t.captionText, width)
	for linecount := 0; linecount < len(paragraph); linecount++ {
		fmt.Fprintln(t.out, paragraph[linecount])
	}
}

// Calculate the total number of characters in a row
func (t Table) getTableWidth() int {
	var chars int
	for _, v := range t.cs {
		chars += v
	}

	// Add chars, spaces, seperators to calculate the total width of the table.
	// ncols := t.colSize
	// spaces := ncols * 2
	// seps := ncols + 1

	return (chars + (3 * t.colSize) + 2)
}

func (t Table) printRows() {
	for i, lines := range t.lines {
		t.printRow(lines, i)
	}
}

func (t *Table) fillAlignment(num int) {
	if len(t.columnsAlign) < num {
		t.columnsAlign = make([]int, num)
		for i := range t.columnsAlign {
			t.columnsAlign[i] = t.align
		}
	}
}

// Print Row Information
// Adjust column alignment based on type

func (t *Table) printRow(columns [][]string, rowIdx int) {
	// Get Maximum Height
	max := t.rs[rowIdx]
	total := len(columns)

	// TODO Fix uneven col size
	// if total < t.colSize {
	//	for n := t.colSize - total; n < t.colSize ; n++ {
	//		columns = append(columns, []string{SPACE})
	//		t.cs[n] = t.mW
	//	}
	//}

	// Pad Each Height
	pads := []int{}

	// Checking for ANSI escape sequences for columns
	is_esc_seq := false
	if len(t.columnsParams) > 0 {
		is_esc_seq = true
	}
	t.fillAlignment(total)

	for i, line := range columns {
		length := len(line)
		pad := max - length
		pads = append(pads, pad)
		for n := 0; n < pad; n++ {
			columns[i] = append(columns[i], "  ")
		}
	}
	//fmt.Println(max, "\n")
	for x := 0; x < max; x++ {
		for y := 0; y < total; y++ {

			// Check if border is set
			if !t.noWhiteSpace {
				fmt.Fprint(t.out, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn))
				fmt.Fprintf(t.out, SPACE)
			}

			str := columns[y][x]

			// Embedding escape sequence with column value
			if is_esc_seq {
				str = format(str, t.columnsParams[y])
			}

			// This would print alignment
			// Default alignment  would use multiple configuration
			switch t.columnsAlign[y] {
			case ALIGN_CENTER: //
				fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y]))
			case ALIGN_RIGHT:
				fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y]))
			case ALIGN_LEFT:
				fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y]))
			default:
				if decimal.MatchString(strings.TrimSpace(str)) || percent.MatchString(strings.TrimSpace(str)) {
					fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y]))
				} else {
					fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y]))

					// TODO Custom alignment per column
					//if max == 1 || pads[y] > 0 {
					//	fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y]))
					//} else {
					//	fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y]))
					//}

				}
			}
			if !t.noWhiteSpace {
				fmt.Fprintf(t.out, SPACE)
			} else {
				fmt.Fprintf(t.out, t.tablePadding)
			}
		}
		// Check if border is set
		// Replace with space if not set
		if !t.noWhiteSpace {
			fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE))
		}
		fmt.Fprint(t.out, t.newLine)
	}

	if t.rowLine {
		t.printLine(true)
	}
}

// Print the rows of the table and merge the cells that are identical
func (t *Table) printRowsMergeCells() {
	var previousLine []string
	var displayCellBorder []bool
	var tmpWriter bytes.Buffer
	for i, lines := range t.lines {
		// We store the display of the current line in a tmp writer, as we need to know which border needs to be print above
		previousLine, displayCellBorder = t.printRowMergeCells(&tmpWriter, lines, i, previousLine)
		if i > 0 { //We don't need to print borders above first line
			if t.rowLine {
				t.printLineOptionalCellSeparators(true, displayCellBorder)
			}
		}
		tmpWriter.WriteTo(t.out)
	}
	//Print the end of the table
	if t.rowLine {
		t.printLine(true)
	}
}

// Print Row Information to a writer and merge identical cells.
// Adjust column alignment based on type

func (t *Table) printRowMergeCells(writer io.Writer, columns [][]string, rowIdx int, previousLine []string) ([]string, []bool) {
	// Get Maximum Height
	max := t.rs[rowIdx]
	total := len(columns)

	// Pad Each Height
	pads := []int{}

	// Checking for ANSI escape sequences for columns
	is_esc_seq := false
	if len(t.columnsParams) > 0 {
		is_esc_seq = true
	}
	for i, line := range columns {
		length := len(line)
		pad := max - length
		pads = append(pads, pad)
		for n := 0; n < pad; n++ {
			columns[i] = append(columns[i], "  ")
		}
	}

	var displayCellBorder []bool
	t.fillAlignment(total)
	for x := 0; x < max; x++ {
		for y := 0; y < total; y++ {

			// Check if border is set
			fmt.Fprint(writer, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn))

			fmt.Fprintf(writer, SPACE)

			str := columns[y][x]

			// Embedding escape sequence with column value
			if is_esc_seq {
				str = format(str, t.columnsParams[y])
			}

			if t.autoMergeCells {
				//Store the full line to merge mutli-lines cells
				fullLine := strings.TrimRight(strings.Join(columns[y], " "), " ")
				if len(previousLine) > y && fullLine == previousLine[y] && fullLine != "" {
					// If this cell is identical to the one above but not empty, we don't display the border and keep the cell empty.
					displayCellBorder = append(displayCellBorder, false)
					str = ""
				} else {
					// First line or different content, keep the content and print the cell border
					displayCellBorder = append(displayCellBorder, true)
				}
			}

			// This would print alignment
			// Default alignment  would use multiple configuration
			switch t.columnsAlign[y] {
			case ALIGN_CENTER: //
				fmt.Fprintf(writer, "%s", Pad(str, SPACE, t.cs[y]))
			case ALIGN_RIGHT:
				fmt.Fprintf(writer, "%s", PadLeft(str, SPACE, t.cs[y]))
			case ALIGN_LEFT:
				fmt.Fprintf(writer, "%s", PadRight(str, SPACE, t.cs[y]))
			default:
				if decimal.MatchString(strings.TrimSpace(str)) || percent.MatchString(strings.TrimSpace(str)) {
					fmt.Fprintf(writer, "%s", PadLeft(str, SPACE, t.cs[y]))
				} else {
					fmt.Fprintf(writer, "%s", PadRight(str, SPACE, t.cs[y]))
				}
			}
			fmt.Fprintf(writer, SPACE)
		}
		// Check if border is set
		// Replace with space if not set
		fmt.Fprint(writer, ConditionString(t.borders.Left, t.pColumn, SPACE))
		fmt.Fprint(writer, t.newLine)
	}

	//The new previous line is the current one
	previousLine = make([]string, total)
	for y := 0; y < total; y++ {
		previousLine[y] = strings.TrimRight(strings.Join(columns[y], " "), " ") //Store the full line for multi-lines cells
	}
	//Returns the newly added line and wether or not a border should be displayed above.
	return previousLine, displayCellBorder
}

func (t *Table) parseDimension(str string, colKey, rowKey int) []string {
	var (
		raw      []string
		maxWidth int
	)

	raw = getLines(str)
	maxWidth = 0
	for _, line := range raw {
		if w := DisplayWidth(line); w > maxWidth {
			maxWidth = w
		}
	}

	// If wrapping, ensure that all paragraphs in the cell fit in the
	// specified width.
	if t.autoWrap {
		// If there's a maximum allowed width for wrapping, use that.
		if maxWidth > t.mW {
			maxWidth = t.mW
		}

		// In the process of doing so, we need to recompute maxWidth. This
		// is because perhaps a word in the cell is longer than the
		// allowed maximum width in t.mW.
		newMaxWidth := maxWidth
		newRaw := make([]string, 0, len(raw))

		if t.reflowText {
			// Make a single paragraph of everything.
			raw = []string{strings.Join(raw, " ")}
		}
		for i, para := range raw {
			paraLines, _ := WrapString(para, maxWidth)
			for _, line := range paraLines {
				if w := DisplayWidth(line); w > newMaxWidth {
					newMaxWidth = w
				}
			}
			if i > 0 {
				newRaw = append(newRaw, " ")
			}
			newRaw = append(newRaw, paraLines...)
		}
		raw = newRaw
		maxWidth = newMaxWidth
	}

	// Store the new known maximum width.
	v, ok := t.cs[colKey]
	if !ok || v < maxWidth || v == 0 {
		t.cs[colKey] = maxWidth
	}

	// Remember the number of lines for the row printer.
	h := len(raw)
	v, ok = t.rs[rowKey]

	if !ok || v < h || v == 0 {
		t.rs[rowKey] = h
	}
	//fmt.Printf("Raw %+v %d\n", raw, len(raw))
	return raw
}
