// Copyright 2011 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 texthtml formats text files to HTML.
package texthtml

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/scanner"
	"go/token"
	"io"
	"regexp"
	"text/template"
)

// A Span describes a text span [start, end).
// The zero value of a Span is an empty span.
type Span struct {
	Start, End int
}

func (s *Span) isEmpty() bool { return s.Start >= s.End }

// A Selection is an "iterator" function returning a text span.
// Repeated calls to a selection return consecutive, non-overlapping,
// non-empty spans, followed by an infinite sequence of empty
// spans. The first empty span marks the end of the selection.
type Selection func() Span

// A Config configures how to format text as HTML.
type Config struct {
	Line       int       // if >= 1, number lines beginning with number Line, with <span class="ln">
	GoComments bool      // mark comments in Go text with <span class="comment">
	Highlight  string    // highlight matches for this regexp with <span class="highlight">
	Selection  Selection // mark selected spans with <span class="selection">
	AST        ast.Node  // link uses to declarations, assuming text is formatting of AST
	OldDocs    bool      // emit links to ?m=old docs
}

// Format formats text to HTML according to the configuration cfg.
func Format(text []byte, cfg Config) (html []byte) {
	var comments, highlights Selection
	if cfg.GoComments {
		comments = tokenSelection(text, token.COMMENT)
	}
	if cfg.Highlight != "" {
		highlights = regexpSelection(text, cfg.Highlight)
	}

	var buf bytes.Buffer
	var idents Selection = Spans()
	var goLinks []goLink
	if cfg.AST != nil {
		idents = tokenSelection(text, token.IDENT)
		goLinks = goLinksFor(cfg.AST)
		if cfg.OldDocs {
			for i := range goLinks {
				goLinks[i].oldDocs = true
			}
		}
	}

	formatSelections(&buf, text, goLinks, comments, highlights, cfg.Selection, idents)

	if cfg.AST != nil {
		postFormatAST(&buf, cfg.AST)
	}

	if cfg.Line > 0 {
		// Add line numbers in a separate pass.
		old := buf.Bytes()
		buf = bytes.Buffer{}
		n := cfg.Line
		for _, line := range bytes.Split(old, []byte("\n")) {
			// The line numbers are inserted into the document via a CSS ::before
			// pseudo-element. This prevents them from being copied when users
			// highlight and copy text.
			// ::before is supported in 98% of browsers: https://caniuse.com/#feat=css-gencontent
			// This is also the trick Github uses to hide line numbers.
			//
			// The first tab for the code snippet needs to start in column 9, so
			// it indents a full 8 spaces, hence the two nbsp's. Otherwise the tab
			// character only indents a short amount.
			//
			// Due to rounding and font width Firefox might not treat 8 rendered
			// characters as 8 characters wide, and subsequently may treat the tab
			// character in the 9th position as moving the width from (7.5 or so) up
			// to 8. See
			// https://github.com/webcompat/web-bugs/issues/17530#issuecomment-402675091
			// for a fuller explanation. The solution is to add a CSS class to
			// explicitly declare the width to be 8 characters.
			fmt.Fprintf(&buf, `<span id="L%d" class="ln">%6d&nbsp;&nbsp;</span>`, n, n)
			n++
			buf.Write(line)
			buf.WriteByte('\n')
		}
	}
	return buf.Bytes()
}

// formatSelections takes a text and writes it to w using link and span
// writers lw and sw as follows: lw is invoked for consecutive span starts
// and ends as specified through the links selection, and sw is invoked for
// consecutive spans of text overlapped by the same selections as specified
// by selections.
func formatSelections(w io.Writer, text []byte, goLinks []goLink, selections ...Selection) {
	// compute the sequence of consecutive span changes
	changes := newMerger(selections)

	// The i'th bit in bitset indicates that the text
	// at the current offset is covered by selections[i].
	bitset := 0
	lastOffs := 0

	// Text spans are written in a delayed fashion
	// such that consecutive spans belonging to the
	// same selection can be combined (peephole optimization).
	// last describes the last span which has not yet been written.
	var last struct {
		begin, end int // valid if begin < end
		bitset     int
	}

	// flush writes the last delayed text span
	flush := func() {
		if last.begin < last.end {
			selectionTag(w, text[last.begin:last.end], last.bitset)
		}
		last.begin = last.end // invalidate last
	}

	// span runs the span [lastOffs, end) with the selection
	// indicated by bitset through the span peephole optimizer.
	span := func(end int) {
		if lastOffs < end { // ignore empty spans
			if last.end != lastOffs || last.bitset != bitset {
				// the last span is not adjacent to or
				// differs from the new one
				flush()
				// start a new span
				last.begin = lastOffs
			}
			last.end = end
			last.bitset = bitset
		}
	}

	linkEnd := ""
	for {
		// get the next span change
		index, offs, start := changes.next()
		if index < 0 || offs > len(text) {
			// no more span changes or the next change
			// is past the end of the text - we're done
			break
		}

		// format the previous selection span, determine
		// the new selection bitset and start a new span
		span(offs)
		if index == 3 { // Go link
			flush()
			if start {
				if len(goLinks) > 0 {
					start, end := goLinks[0].tags()
					io.WriteString(w, start)
					linkEnd = end
					goLinks = goLinks[1:]
				}
			} else {
				if linkEnd != "" {
					io.WriteString(w, linkEnd)
					linkEnd = ""
				}
			}
		} else {
			mask := 1 << uint(index)
			if start {
				bitset |= mask
			} else {
				bitset &^= mask
			}
		}
		lastOffs = offs
	}
	span(len(text))
	flush()
}

// A merger merges a slice of Selections and produces a sequence of
// consecutive span change events through repeated next() calls.
type merger struct {
	selections []Selection
	spans      []Span // spans[i] is the next span of selections[i]
}

const infinity int = 2e9

func newMerger(selections []Selection) *merger {
	spans := make([]Span, len(selections))
	for i, sel := range selections {
		spans[i] = Span{infinity, infinity}
		if sel != nil {
			if seg := sel(); !seg.isEmpty() {
				spans[i] = seg
			}
		}
	}
	return &merger{selections, spans}
}

// next returns the next span change: index specifies the Selection
// to which the span belongs, offs is the span start or end offset
// as determined by the start value. If there are no more span changes,
// next returns an index value < 0.
func (m *merger) next() (index, offs int, start bool) {
	// find the next smallest offset where a span starts or ends
	offs = infinity
	index = -1
	for i, seg := range m.spans {
		switch {
		case seg.Start < offs:
			offs = seg.Start
			index = i
			start = true
		case seg.End < offs:
			offs = seg.End
			index = i
			start = false
		}
	}
	if index < 0 {
		// no offset found => all selections merged
		return
	}
	// offset found - it's either the start or end offset but
	// either way it is ok to consume the start offset: set it
	// to infinity so it won't be considered in the following
	// next call
	m.spans[index].Start = infinity
	if start {
		return
	}
	// end offset found - consume it
	m.spans[index].End = infinity
	// advance to the next span for that selection
	seg := m.selections[index]()
	if !seg.isEmpty() {
		m.spans[index] = seg
	}
	return
}

// lineSelection returns the line spans for text as a Selection.
func lineSelection(text []byte) Selection {
	i, j := 0, 0
	return func() (seg Span) {
		// find next newline, if any
		for j < len(text) {
			j++
			if text[j-1] == '\n' {
				break
			}
		}
		if i < j {
			// text[i:j] constitutes a line
			seg = Span{i, j}
			i = j
		}
		return
	}
}

// tokenSelection returns, as a selection, the sequence of
// consecutive occurrences of token sel in the Go src text.
func tokenSelection(src []byte, sel token.Token) Selection {
	var s scanner.Scanner
	fset := token.NewFileSet()
	file := fset.AddFile("", fset.Base(), len(src))
	s.Init(file, src, nil, scanner.ScanComments)
	return func() (seg Span) {
		for {
			pos, tok, lit := s.Scan()
			if tok == token.EOF {
				break
			}
			offs := file.Offset(pos)
			if tok == sel {
				seg = Span{offs, offs + len(lit)}
				break
			}
		}
		return
	}
}

// Spans is a helper function to make a Selection from a slice of spans.
// Empty spans are discarded.
func Spans(spans ...Span) Selection {
	i := 0
	return func() Span {
		for i < len(spans) {
			s := spans[i]
			i++
			if s.Start < s.End {
				// non-empty
				return s
			}
		}
		return Span{}
	}
}

// regexpSelection computes the Selection for the regular expression expr in text.
func regexpSelection(text []byte, expr string) Selection {
	var matches [][]int
	if rx, err := regexp.Compile(expr); err == nil {
		matches = rx.FindAllIndex(text, -1)
	}
	var spans []Span
	for _, m := range matches {
		spans = append(spans, Span{m[0], m[1]})
	}
	return Spans(spans...)
}

// Span tags for all the possible selection combinations that may
// be generated by FormatText. Selections are indicated by a bitset,
// and the value of the bitset specifies the tag to be used.
//
// bit 0: comments
// bit 1: highlights
// bit 2: selections
//
var startTags = [][]byte{
	/* 000 */ []byte(``),
	/* 001 */ []byte(`<span class="comment">`),
	/* 010 */ []byte(`<span class="highlight">`),
	/* 011 */ []byte(`<span class="highlight-comment">`),
	/* 100 */ []byte(`<span class="selection">`),
	/* 101 */ []byte(`<span class="selection-comment">`),
	/* 110 */ []byte(`<span class="selection-highlight">`),
	/* 111 */ []byte(`<span class="selection-highlight-comment">`),
}

var endTag = []byte(`</span>`)

func selectionTag(w io.Writer, text []byte, selections int) {
	if selections < len(startTags) {
		if tag := startTags[selections]; len(tag) > 0 {
			w.Write(tag)
			template.HTMLEscape(w, text)
			w.Write(endTag)
			return
		}
	}
	template.HTMLEscape(w, text)
}
