// Copyright 2009 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 godoc

// This file contains the mechanism to "linkify" html source
// text containing EBNF sections (as found in go_spec.html).
// The result is the input source text with the EBNF sections
// modified such that identifiers are linked to the respective
// definitions.

import (
	"bytes"
	"fmt"
	"io"
	"text/scanner"
)

type ebnfParser struct {
	out     io.Writer // parser output
	src     []byte    // parser input
	scanner scanner.Scanner
	prev    int    // offset of previous token
	pos     int    // offset of current token
	tok     rune   // one token look-ahead
	lit     string // token literal
}

func (p *ebnfParser) flush() {
	p.out.Write(p.src[p.prev:p.pos])
	p.prev = p.pos
}

func (p *ebnfParser) next() {
	p.tok = p.scanner.Scan()
	p.pos = p.scanner.Position.Offset
	p.lit = p.scanner.TokenText()
}

func (p *ebnfParser) printf(format string, args ...any) {
	p.flush()
	fmt.Fprintf(p.out, format, args...)
}

func (p *ebnfParser) errorExpected(msg string) {
	p.printf(`<span class="highlight">error: expected %s, found %s</span>`, msg, scanner.TokenString(p.tok))
}

func (p *ebnfParser) expect(tok rune) {
	if p.tok != tok {
		p.errorExpected(scanner.TokenString(tok))
	}
	p.next() // make progress in any case
}

func (p *ebnfParser) parseIdentifier(def bool) {
	if p.tok == scanner.Ident {
		name := p.lit
		if def {
			p.printf(`<a id="%s">%s</a>`, name, name)
		} else {
			p.printf(`<a href="#%s" class="noline">%s</a>`, name, name)
		}
		p.prev += len(name) // skip identifier when printing next time
		p.next()
	} else {
		p.expect(scanner.Ident)
	}
}

func (p *ebnfParser) parseTerm() bool {
	switch p.tok {
	case scanner.Ident:
		p.parseIdentifier(false)

	case scanner.String, scanner.RawString:
		p.next()
		const ellipsis = '…' // U+2026, the horizontal ellipsis character
		if p.tok == ellipsis {
			p.next()
			p.expect(scanner.String)
		}

	case '(':
		p.next()
		p.parseExpression()
		p.expect(')')

	case '[':
		p.next()
		p.parseExpression()
		p.expect(']')

	case '{':
		p.next()
		p.parseExpression()
		p.expect('}')

	default:
		return false // no term found
	}

	return true
}

func (p *ebnfParser) parseSequence() {
	if !p.parseTerm() {
		p.errorExpected("term")
	}
	for p.parseTerm() {
	}
}

func (p *ebnfParser) parseExpression() {
	for {
		p.parseSequence()
		if p.tok != '|' {
			break
		}
		p.next()
	}
}

func (p *ebnfParser) parseProduction() {
	p.parseIdentifier(true)
	p.expect('=')
	if p.tok != '.' {
		p.parseExpression()
	}
	p.expect('.')
}

func (p *ebnfParser) parse(out io.Writer, src []byte) {
	// initialize ebnfParser
	p.out = out
	p.src = src
	p.scanner.Init(bytes.NewBuffer(src))
	p.next() // initializes pos, tok, lit

	// process source
	for p.tok != scanner.EOF {
		p.parseProduction()
	}
	p.flush()
}

// Markers around EBNF sections
var (
	openTag  = []byte(`<pre class="ebnf">`)
	closeTag = []byte(`</pre>`)
)

func Linkify(out io.Writer, src []byte) {
	for len(src) > 0 {
		// i: beginning of EBNF text (or end of source)
		i := bytes.Index(src, openTag)
		if i < 0 {
			i = len(src) - len(openTag)
		}
		i += len(openTag)

		// j: end of EBNF text (or end of source)
		j := bytes.Index(src[i:], closeTag) // close marker
		if j < 0 {
			j = len(src) - i
		}
		j += i

		// write text before EBNF
		out.Write(src[0:i])
		// process EBNF
		var p ebnfParser
		p.parse(out, src[i:j])

		// advance
		src = src[j:]
	}
}
