package textutil

import (
	"fmt"
	"io"
	"unicode"
)

// LineWriter implements an io.Writer filter that formats input text into output
// lines with a given target width in runes.
//
// Each input rune is classified into one of three kinds:
//   EOL:    end-of-line, consisting of \f, \n, \r, \v, U+2028 or U+2029
//   Space:  defined by unicode.IsSpace
//   Letter: everything else
//
// The input text is expected to consist of words, defined as sequences of
// letters.  Sequences of words form paragraphs, where paragraphs are separated
// by either blank lines (that contain no letters), or an explicit U+2029
// ParagraphSeparator.  Input lines with leading spaces are treated verbatim.
//
// Paragraphs are output as word-wrapped lines; line breaks only occur at word
// boundaries.  Output lines are usually no longer than the target width.  The
// exceptions are single words longer than the target width, which are output on
// their own line, and verbatim lines, which may be arbitrarily longer or
// shorter than the width.
//
// Output lines never contain trailing spaces.  Only verbatim output lines may
// contain leading spaces.  Spaces separating input words are output verbatim,
// unless it would result in a line with leading or trailing spaces.
//
// EOL runes within the input text are never written to the output; the output
// line terminator and paragraph separator may be configured, and some EOL may
// be output as a single space ' ' to maintain word separation.
//
// The algorithm greedily fills each output line with as many words as it can,
// assuming that all Unicode code points have the same width.  Invalid UTF-8 is
// silently transformed to the replacement character U+FFFD and treated as a
// single rune.
//
// Flush must be called after the last call to Write; the input is buffered.
//
//   Implementation note: line breaking is a complicated topic.  This approach
//   attempts to be simple and useful; a full implementation conforming to
//   Unicode Standard Annex #14 would be complicated, and is not implemented.
//   Languages that don't use spaces to separate words (e.g. CJK) won't work
//   well under the current approach.
//
//   http://www.unicode.org/reports/tr14 [Unicode Line Breaking Algorithm]
//   http://www.unicode.org/versions/Unicode4.0.0/ch05.pdf [5.8 Newline Guidelines]
type LineWriter struct {
	// State configured by the user.
	w            io.Writer
	runeDecoder  RuneChunkDecoder
	width        runePos
	lineTerm     []byte
	paragraphSep string
	indents      []string

	// The buffer contains a single output line.
	lineBuf byteRuneBuffer

	// Keep track of the previous state and rune.
	prevState state
	prevRune  rune

	// Keep track of blank input lines.
	inputLineHasLetter bool

	// lineBuf positions where the line starts (after separators and indents), a
	// new word has started and the last word has ended.
	lineStart    bytePos
	newWordStart bytePos
	lastWordEnd  bytePos

	// Keep track of paragraph terminations and line indices, so we can output the
	// paragraph separator and indents correctly.
	terminateParagraph bool
	paragraphLineIndex int
	wroteFirstLine     bool
}

type state int

const (
	stateWordWrap  state = iota // Perform word-wrapping [start state]
	stateVerbatim               // Verbatim output-line, no word-wrapping
	stateSkipSpace              // Skip spaces in input line.
)

// NewLineWriter returns a new LineWriter with the given target width in runes,
// producing output on the underlying writer w.  The dec and enc are used to
// respectively decode runes from Write calls, and encode runes to w.
func NewLineWriter(w io.Writer, width int, dec RuneChunkDecoder, enc RuneEncoder) *LineWriter {
	ret := &LineWriter{
		w:            w,
		runeDecoder:  dec,
		width:        runePos(width),
		lineTerm:     []byte("\n"),
		paragraphSep: "\n",
		prevState:    stateWordWrap,
		prevRune:     LineSeparator,
		lineBuf:      byteRuneBuffer{enc: enc},
	}
	ret.resetLine()
	return ret
}

// NewUTF8LineWriter returns a new LineWriter filter that implements io.Writer,
// and decodes and encodes runes in UTF-8.
func NewUTF8LineWriter(w io.Writer, width int) *LineWriter {
	return NewLineWriter(w, width, &UTF8ChunkDecoder{}, UTF8Encoder{})
}

// Width returns the target width in runes.  If width < 0 the width is
// unlimited; each paragraph is output as a single line.
func (w *LineWriter) Width() int { return int(w.width) }

// SetLineTerminator sets the line terminator for subsequent Write calls.  Every
// output line is terminated with term; EOL runes from the input are never
// written to the output.  A new LineWriter instance uses "\n" as the default
// line terminator.
//
// Calls Flush internally, and returns any Flush error.
func (w *LineWriter) SetLineTerminator(term string) error {
	if err := w.Flush(); err != nil {
		return err
	}
	w.lineTerm = []byte(term)
	w.resetLine()
	return nil
}

// SetParagraphSeparator sets the paragraph separator for subsequent Write
// calls.  Every consecutive pair of non-empty paragraphs is separated with sep;
// EOL runes from the input are never written to the output.  A new LineWriter
// instance uses "\n" as the default paragraph separator.
//
// Calls Flush internally, and returns any Flush error.
func (w *LineWriter) SetParagraphSeparator(sep string) error {
	if err := w.Flush(); err != nil {
		return err
	}
	w.paragraphSep = sep
	w.resetLine()
	return nil
}

// SetIndents sets the indentation for subsequent Write calls.  Multiple indents
// may be set, corresponding to the indent to use for the corresponding
// paragraph line.  E.g. SetIndents("AA", "BBB", C") means the first line in
// each paragraph is indented with "AA", the second line in each paragraph is
// indented with "BBB", and all subsequent lines in each paragraph are indented
// with "C".
//
// SetIndents() is equivalent to SetIndents(""), SetIndents("", ""), etc.
//
// A new LineWriter instance has no indents by default.
//
// Calls Flush internally, and returns any Flush error.
func (w *LineWriter) SetIndents(indents ...string) error {
	if err := w.Flush(); err != nil {
		return err
	}
	// Copy indents in case the user passed the slice via SetIndents(p...), and
	// canonicalize the all empty case to nil.
	allEmpty := true
	w.indents = make([]string, len(indents))
	for ix, indent := range indents {
		w.indents[ix] = indent
		if indent != "" {
			allEmpty = false
		}
	}
	if allEmpty {
		w.indents = nil
	}
	w.resetLine()
	return nil
}

// Write implements io.Writer by buffering data into the LineWriter w.  Actual
// writes to the underlying writer may occur, and may include data buffered in
// either this Write call or previous Write calls.
//
// Flush must be called after the last call to Write.
func (w *LineWriter) Write(data []byte) (int, error) {
	return RuneChunkWrite(w.runeDecoder, w.addRune, data)
}

// Flush flushes any remaining buffered text, and resets the paragraph line
// count back to 0, so that indents will be applied starting from the first
// line.  It does not imply a paragraph separator; repeated calls to Flush with
// no intervening calls to other methods is equivalent to a single Flush.
//
// Flush must be called after the last call to Write, and may be called an
// arbitrary number of times before the last Write.
func (w *LineWriter) Flush() error {
	if err := RuneChunkFlush(w.runeDecoder, w.addRune); err != nil {
		return err
	}
	// Add U+2028 to force the last line (if any) to be written.
	if err := w.addRune(LineSeparator); err != nil {
		return err
	}
	// Reset the paragraph line count.
	w.paragraphLineIndex = 0
	w.resetLine()
	return nil
}

// addRune is called every time w.runeDecoder decodes a full rune.
func (w *LineWriter) addRune(r rune) error {
	state, lineBreak := w.nextState(r, w.updateRune(r))
	if lineBreak {
		if err := w.writeLine(); err != nil {
			return err
		}
	}
	w.bufferRune(r, state, lineBreak)
	w.prevState = state
	w.prevRune = r
	return nil
}

// We classify each incoming rune into three kinds for easier handling.
type kind int

const (
	kindEOL kind = iota
	kindSpace
	kindLetter
)

func runeKind(r rune) kind {
	switch r {
	case '\f', '\n', '\r', '\v', LineSeparator, ParagraphSeparator:
		return kindEOL
	}
	if unicode.IsSpace(r) {
		return kindSpace
	}
	return kindLetter
}

func (w *LineWriter) updateRune(r rune) bool {
	forceLineBreak := false
	switch kind := runeKind(r); kind {
	case kindEOL:
		// Update lastWordEnd if the last word just ended.
		if w.newWordStart != -1 {
			w.newWordStart = -1
			w.lastWordEnd = w.lineBuf.ByteLen()
		}
		switch {
		case w.prevRune == '\r' && r == '\n':
			// Treat "\r\n" as a single EOL; we've already handled the logic for '\r',
			// so there's nothing to do when we see '\n'.
		case r == LineSeparator:
			// Treat U+2028 as a pure line break; it's never a paragraph break.
			forceLineBreak = true
		case r == ParagraphSeparator || !w.inputLineHasLetter:
			// The paragraph has just been terminated if we see an explicit U+2029, or
			// if we see a blank line, which may contain spaces.
			forceLineBreak = true
			w.terminateParagraph = true
		}
		w.inputLineHasLetter = false
	case kindSpace:
		// Update lastWordEnd if the last word just ended.
		if w.newWordStart != -1 {
			w.newWordStart = -1
			w.lastWordEnd = w.lineBuf.ByteLen()
		}
	case kindLetter:
		// Update newWordStart if a new word just started.
		if w.newWordStart == -1 {
			w.newWordStart = w.lineBuf.ByteLen()
		}
		w.inputLineHasLetter = true
		w.terminateParagraph = false
	default:
		panic(fmt.Errorf("textutil: updateRune unhandled kind %d", kind))
	}
	return forceLineBreak
}

// nextState returns the next state and whether we should break the line.
//
// Here's a handy table that describes all the scenarios in which we will line
// break input text, grouped by the reason for the break.  The current position
// is the last non-* rune in each pattern, which is where we decide to break.
//
//              w.prevState   Next state   Buffer reset
//              -----------   ----------   ------------
//   ===== Force line break (U+2028 / U+2029, blank line) =====
//   a..*|***   *             wordWrap     empty
//   a._.|***   *             wordWrap     empty
//   a+**|***   *             wordWrap     empty
//
//   ===== verbatim: wait for any EOL =====
//   _*.*|***   verbatim      wordWrap     empty
//
//   ===== wordWrap: switch to verbatim =====
//   a._*|***   wordWrap      verbatim     empty
//
//   ===== wordWrap: line is too wide =====
//   abc.|***   wordWrap      wordWrap     empty
//   abcd|.**   wordWrap      wordWrap     empty
//   abcd|e.*   wordWrap      wordWrap     empty
//   a_cd|.**   wordWrap      wordWrap     empty
//
//   abc_|***   wordWrap      skipSpace    empty
//   abcd|_**   wordWrap      skipSpace    empty
//   abcd|e_*   wordWrap      skipSpace    empty
//   a_cd|_**   wordWrap      skipSpace    empty
//
//   a_cd|e**   wordWrap      start        newWordStart
//
//   LEGEND
//     abcde  Letter
//     .      End-of-line
//     +      End-of-line (only U+2028 / U+2029)
//     _      Space
//     *      Any rune (letter, line-end or space)
//     |      Visual indication of width=4, has no width itself.
//
// Note that Flush calls behave exactly as if an explicit U+2028 line separator
// were added to the end of all buffered data.
func (w *LineWriter) nextState(r rune, forceLineBreak bool) (state, bool) {
	if forceLineBreak {
		return stateWordWrap, true
	}
	kind := runeKind(r)
	// Handle non word-wrap states, which are easy.
	switch w.prevState {
	case stateVerbatim:
		if kind == kindEOL {
			return stateWordWrap, true
		}
		return stateVerbatim, false
	case stateSkipSpace:
		if kind == kindSpace {
			return stateSkipSpace, false
		}
		return stateWordWrap, false
	}
	// Handle stateWordWrap, which is more complicated.

	// Switch to the verbatim state when we see a space right after an EOL.
	if runeKind(w.prevRune) == kindEOL && kind == kindSpace {
		return stateVerbatim, true
	}
	// Break on EOL or space when the line is too wide.  See above table.
	if w.width >= 0 && w.width <= w.lineBuf.RuneLen()+1 {
		switch kind {
		case kindEOL:
			return stateWordWrap, true
		case kindSpace:
			return stateSkipSpace, true
		}
		// case kindLetter falls through
	}
	// Handle the newWordStart case in the above table.
	if w.width >= 0 && w.width < w.lineBuf.RuneLen()+1 && w.newWordStart != w.lineStart {
		return stateWordWrap, true
	}
	// Stay in the wordWrap state and don't break the line.
	return stateWordWrap, false
}

func (w *LineWriter) writeLine() error {
	if w.lastWordEnd == -1 {
		// Don't write blank lines, but we must reset the line in case the paragraph
		// has just been terminated.
		w.resetLine()
		return nil
	}
	// Write the line (without trailing spaces) followed by the line terminator.
	line := w.lineBuf.Bytes()[:w.lastWordEnd]
	if _, err := w.w.Write(line); err != nil {
		return err
	}
	if _, err := w.w.Write(w.lineTerm); err != nil {
		return err
	}
	// Reset the line buffer.
	w.wroteFirstLine = true
	w.paragraphLineIndex++
	if w.newWordStart != -1 {
		// If we have an unterminated new word, we must be in the newWordStart case
		// in the table above.  Handle the special buffer reset here.
		newWord := string(w.lineBuf.Bytes()[w.newWordStart:])
		w.resetLine()
		w.newWordStart = w.lineBuf.ByteLen()
		w.lineBuf.WriteString(newWord)
	} else {
		w.resetLine()
	}
	return nil
}

func (w *LineWriter) resetLine() {
	w.lineBuf.Reset()
	w.newWordStart = -1
	w.lastWordEnd = -1
	// Write the paragraph separator if the previous paragraph has terminated.
	// This consumes no runes from the line width.
	if w.wroteFirstLine && w.terminateParagraph {
		w.lineBuf.WriteString0Runes(w.paragraphSep)
		w.paragraphLineIndex = 0
	}
	// Add indent; a non-empty indent consumes runes from the line width.
	var indent string
	switch {
	case w.paragraphLineIndex < len(w.indents):
		indent = w.indents[w.paragraphLineIndex]
	case len(w.indents) > 0:
		indent = w.indents[len(w.indents)-1]
	}
	w.lineBuf.WriteString(indent)
	w.lineStart = w.lineBuf.ByteLen()
}

func (w *LineWriter) bufferRune(r rune, state state, lineBreak bool) {
	// Never add leading spaces to the buffer in the wordWrap state.
	wordWrapNoLeadingSpaces := state == stateWordWrap && !lineBreak
	switch kind := runeKind(r); kind {
	case kindEOL:
		// When we're word-wrapping and we see a letter followed by EOL, we convert
		// the EOL into a single space in the buffer, to break the previous word
		// from the next word.
		if wordWrapNoLeadingSpaces && runeKind(w.prevRune) == kindLetter {
			w.lineBuf.WriteRune(' ')
		}
	case kindSpace:
		if wordWrapNoLeadingSpaces || state == stateVerbatim {
			w.lineBuf.WriteRune(r)
		}
	case kindLetter:
		w.lineBuf.WriteRune(r)
	default:
		panic(fmt.Errorf("textutil: bufferRune unhandled kind %d", kind))
	}
}
