// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package texttab

import (
	"fmt"
	"io"
	"sort"
	"strings"
	"unicode/utf8"
)

// Table does layout of text-based tables.
//
// Many of its methods return the textTable so callers can easily
// chain them to build up many cells at once.
type Table struct {
	cells []textCell
	cols  int

	shrink []bool

	curRow, curCol int
}

type textCell struct {
	row, col, span int
	value          string
	leftMargin     string
	alignment      align
}

type CellOption func(c *textCell)

func LeftMargin(x string) CellOption {
	return func(c *textCell) {
		c.leftMargin = x
	}
}

var (
	Left   CellOption = func(c *textCell) { c.alignment = alignLeft }
	Center            = func(c *textCell) { c.alignment = alignCenter }
	Right             = func(c *textCell) { c.alignment = alignRight }
)

type align int

const (
	alignLeft align = iota
	alignCenter
	alignRight
)

func (a align) lpad(s string, w int) string {
	switch a {
	default:
		return s
	case alignCenter:
		l := (w - utf8.RuneCountInString(s)) / 2
		return fmt.Sprintf("%*s%s", l, "", s)
	case alignRight:
		return fmt.Sprintf("%*s", w, s)
	}
}

// Row starts a new row in table t.
func (t *Table) Row() *Table {
	if len(t.cells) > 0 {
		t.curRow++
	}
	t.curCol = 0
	return t
}

// Col skips to column "col" in table t. Columns are numbered starting
// at 0.
func (t *Table) Col(col int) *Table {
	if col < t.curCol {
		panic(fmt.Sprintf("cannot move from column %d to earlier column %d", t.curCol, col))
	}
	t.curCol = col
	return t
}

// CurCol returns the current column index.
func (t *Table) CurCol() int {
	return t.curCol
}

// Cell adds a single-column cell at the current row and column.
func (t *Table) Cell(value string, opts ...CellOption) *Table {
	return t.Span(1, value, opts...)
}

// Span adds a multi-column cell at the current row and column.
func (t *Table) Span(cols int, value string, opts ...CellOption) *Table {
	lMargin := " "
	if t.curCol == 0 || len(value) == 0 {
		// For the left-most column or empty cells, we default
		// to no left margin.
		lMargin = ""
	}
	t.cells = append(t.cells, textCell{t.curRow, t.curCol, cols, value, lMargin, alignLeft})
	for _, o := range opts {
		o(&t.cells[len(t.cells)-1])
	}

	t.curCol += cols
	if t.curCol > t.cols {
		t.cols = t.curCol
	}

	return t
}

// SetShrink marks a column as a "shrink" column, which will have
// minimum width.
func (t *Table) SetShrink(col int, shrink bool) {
	for len(t.shrink) < col+1 {
		t.shrink = append(t.shrink, false)
	}
	t.shrink[col] = shrink
}

// Format lays out table t and writes it to w.
func (t *Table) Format(w io.Writer) error {
	shrink := func(col int) bool {
		if col < len(t.shrink) {
			return t.shrink[col]
		}
		return false
	}

	// Collect max length margin for each column.
	lmargin := make([]int, t.cols)
	for _, cell := range t.cells {
		lmargin[cell.col] = max(utf8.RuneCountInString(cell.leftMargin), lmargin[cell.col])
	}

	// Compute column widths, including their left margins.
	ws := make([]int, t.cols)
	// Consider cells in increasing span width.
	sort.Slice(t.cells, func(i, j int) bool {
		return t.cells[i].span < t.cells[j].span
	})
	var spanCols []int
	for _, cell := range t.cells {
		w := utf8.RuneCountInString(cell.value) + lmargin[cell.col]

		if cell.span == 1 {
			// Easy case.
			ws[cell.col] = max(ws[cell.col], w)
			continue
		}

		// This cell spans multiple columns. Is the total
		// width of those columns already sufficient?
		tw := 0
		for col := cell.col; col < cell.col+cell.span; col++ {
			tw += ws[col]
		}
		if tw >= w {
			continue
		}

		// We need to expand columns. The goal is to expand
		// them all to the necessary average, but some may
		// already be wider than this average. Hence, we
		// process columns from widest to narrowest,
		// subtracting out the columns that are already wider
		// than the target average (which in turn changes the
		// target), and then distributing the remaining space
		// among the narrower ones.
		spanCols = spanCols[:0]
		for col := cell.col; col < cell.col+cell.span; col++ {
			if shrink(col) {
				// We can't grow a shrink column, so
				// account for its space, but don't
				// add it to the columns to adjust.
				w -= ws[col]
			} else {
				spanCols = append(spanCols, col)
			}
		}
		// Process the wider columns first.
		sort.Slice(spanCols, func(i, j int) bool {
			return ws[spanCols[i]] > ws[spanCols[j]]
		})
		span := len(spanCols)
		for _, col := range spanCols {
			// What's the target average width at this
			// point? Round up w/span.
			avg := (w + span - 1) / span
			// Expand column if it isn't wide enough.
			ws[col] = max(ws[col], avg)
			// Subtract this column from the space needed.
			// If the column was already wide enough, this
			// will redistribute its excess across the
			// smaller columns. We also do this if we
			// expanded the column as a convenient way to
			// spread out the integer rounding of avg.
			w -= ws[col]
			span--
		}
	}

	// Convert column widths into starting offsets. The offset of
	// column i is where i's left margin begins. The slice
	// includes a final offset for the width of the table.
	offs := make([]int, t.cols+1)
	off := 0
	for i, w := range ws {
		offs[i] = off
		off += w
	}
	offs[len(ws)] = off

	const debugPrintColumns = false
	if debugPrintColumns {
		fmt.Println(ws)
		pos := 0
		for col, off := range offs {
			fmt.Fprintf(w, "%*s", off-pos, "")
			pos = off
			for i := 0; i < lmargin[col]; i++ {
				fmt.Fprintf(w, "|")
				pos++
			}
		}
		fmt.Fprint(w, "\n")
	}

	// Format the table. Put the cells back into top-to-bottom
	// left-to-right order.
	sort.Slice(t.cells, func(i, j int) bool {
		if t.cells[i].row != t.cells[j].row {
			return t.cells[i].row < t.cells[j].row
		}
		return t.cells[i].col < t.cells[j].col
	})
	row, off := 0, 0
	for _, cell := range t.cells {
		if strings.TrimSpace(cell.value) == "" && strings.TrimSpace(cell.leftMargin) == "" {
			// Skip empty cells. This avoids printing
			// unnecessary trailing spaces if cells appear
			// at the end of a row.
			continue
		}

		// Get to cell's row.
		for cell.row > row {
			if _, err := fmt.Fprintf(w, "\n"); err != nil {
				return err
			}
			row++
			off = 0
		}

		// Space to the cell's starting offset and print its
		// left margin.
		spaces := offs[cell.col] - off
		if _, err := fmt.Fprintf(w, "%*s%*s", spaces, "", lmargin[cell.col], cell.leftMargin); err != nil {
			return err
		}
		off += spaces + lmargin[cell.col]

		// Compute total cell width, excluding the margin we
		// just printed.
		tw := offs[cell.col+cell.span] - offs[cell.col] - lmargin[cell.col]

		// Print cell contents.
		s := cell.alignment.lpad(cell.value, tw)
		if _, err := fmt.Fprintf(w, "%s", s); err != nil {
			return err
		}
		off += utf8.RuneCountInString(s)
	}
	if len(t.cells) > 0 {
		if _, err := fmt.Fprintf(w, "\n"); err != nil {
			return err
		}
	}

	return nil
}
