// 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 constraint implements parsing and evaluation of build constraint lines.
// See https://golang.org/cmd/go/#hdr-Build_constraints for documentation about build constraints themselves.
//
// This package parses both the original “// +build” syntax and the “//go:build” syntax that will be added in Go 1.17.
// The parser is being included in Go 1.16 to allow tools that need to process Go 1.17 source code
// to still be built against the Go 1.16 release.
// See https://golang.org/design/draft-gobuild for details about the “//go:build” syntax.
package constraint

import (
	"errors"
	"strings"
	"unicode"
	"unicode/utf8"
)

// An Expr is a build tag constraint expression.
// The underlying concrete type is *AndExpr, *OrExpr, *NotExpr, or *TagExpr.
type Expr interface {
	// String returns the string form of the expression,
	// using the boolean syntax used in //go:build lines.
	String() string

	// Eval reports whether the expression evaluates to true.
	// It calls ok(tag) as needed to find out whether a given build tag
	// is satisfied by the current build configuration.
	Eval(ok func(tag string) bool) bool

	// The presence of an isExpr method explicitly marks the type as an Expr.
	// Only implementations in this package should be used as Exprs.
	isExpr()
}

// A TagExpr is an Expr for the single tag Tag.
type TagExpr struct {
	Tag string // for example, “linux” or “cgo”
}

func (x *TagExpr) isExpr() {}

func (x *TagExpr) Eval(ok func(tag string) bool) bool {
	return ok(x.Tag)
}

func (x *TagExpr) String() string {
	return x.Tag
}

func tag(tag string) Expr { return &TagExpr{tag} }

// A NotExpr represents the expression !X (the negation of X).
type NotExpr struct {
	X Expr
}

func (x *NotExpr) isExpr() {}

func (x *NotExpr) Eval(ok func(tag string) bool) bool {
	return !x.X.Eval(ok)
}

func (x *NotExpr) String() string {
	s := x.X.String()
	switch x.X.(type) {
	case *AndExpr, *OrExpr:
		s = "(" + s + ")"
	}
	return "!" + s
}

func not(x Expr) Expr { return &NotExpr{x} }

// An AndExpr represents the expression X && Y.
type AndExpr struct {
	X, Y Expr
}

func (x *AndExpr) isExpr() {}

func (x *AndExpr) Eval(ok func(tag string) bool) bool {
	// Note: Eval both, to make sure ok func observes all tags.
	xok := x.X.Eval(ok)
	yok := x.Y.Eval(ok)
	return xok && yok
}

func (x *AndExpr) String() string {
	return andArg(x.X) + " && " + andArg(x.Y)
}

func andArg(x Expr) string {
	s := x.String()
	if _, ok := x.(*OrExpr); ok {
		s = "(" + s + ")"
	}
	return s
}

func and(x, y Expr) Expr {
	return &AndExpr{x, y}
}

// An OrExpr represents the expression X || Y.
type OrExpr struct {
	X, Y Expr
}

func (x *OrExpr) isExpr() {}

func (x *OrExpr) Eval(ok func(tag string) bool) bool {
	// Note: Eval both, to make sure ok func observes all tags.
	xok := x.X.Eval(ok)
	yok := x.Y.Eval(ok)
	return xok || yok
}

func (x *OrExpr) String() string {
	return orArg(x.X) + " || " + orArg(x.Y)
}

func orArg(x Expr) string {
	s := x.String()
	if _, ok := x.(*AndExpr); ok {
		s = "(" + s + ")"
	}
	return s
}

func or(x, y Expr) Expr {
	return &OrExpr{x, y}
}

// A SyntaxError reports a syntax error in a parsed build expression.
type SyntaxError struct {
	Offset int    // byte offset in input where error was detected
	Err    string // description of error
}

func (e *SyntaxError) Error() string {
	return e.Err
}

var errNotConstraint = errors.New("not a build constraint")

// Parse parses a single build constraint line of the form “//go:build ...” or “// +build ...”
// and returns the corresponding boolean expression.
func Parse(line string) (Expr, error) {
	if text, ok := splitGoBuild(line); ok {
		return parseExpr(text)
	}
	if text, ok := splitPlusBuild(line); ok {
		return parsePlusBuildExpr(text), nil
	}
	return nil, errNotConstraint
}

// IsGoBuild reports whether the line of text is a “//go:build” constraint.
// It only checks the prefix of the text, not that the expression itself parses.
func IsGoBuild(line string) bool {
	_, ok := splitGoBuild(line)
	return ok
}

// splitGoBuild splits apart the leading //go:build prefix in line from the build expression itself.
// It returns "", false if the input is not a //go:build line or if the input contains multiple lines.
func splitGoBuild(line string) (expr string, ok bool) {
	// A single trailing newline is OK; otherwise multiple lines are not.
	if len(line) > 0 && line[len(line)-1] == '\n' {
		line = line[:len(line)-1]
	}
	if strings.Contains(line, "\n") {
		return "", false
	}

	if !strings.HasPrefix(line, "//go:build") {
		return "", false
	}

	line = strings.TrimSpace(line)
	line = line[len("//go:build"):]

	// If strings.TrimSpace finds more to trim after removing the //go:build prefix,
	// it means that the prefix was followed by a space, making this a //go:build line
	// (as opposed to a //go:buildsomethingelse line).
	// If line is empty, we had "//go:build" by itself, which also counts.
	trim := strings.TrimSpace(line)
	if len(line) == len(trim) && line != "" {
		return "", false
	}

	return trim, true
}

// An exprParser holds state for parsing a build expression.
type exprParser struct {
	s string // input string
	i int    // next read location in s

	tok   string // last token read
	isTag bool
	pos   int // position (start) of last token
}

// parseExpr parses a boolean build tag expression.
func parseExpr(text string) (x Expr, err error) {
	defer func() {
		if e := recover(); e != nil {
			if e, ok := e.(*SyntaxError); ok {
				err = e
				return
			}
			panic(e) // unreachable unless parser has a bug
		}
	}()

	p := &exprParser{s: text}
	x = p.or()
	if p.tok != "" {
		panic(&SyntaxError{Offset: p.pos, Err: "unexpected token " + p.tok})
	}
	return x, nil
}

// or parses a sequence of || expressions.
// On entry, the next input token has not yet been lexed.
// On exit, the next input token has been lexed and is in p.tok.
func (p *exprParser) or() Expr {
	x := p.and()
	for p.tok == "||" {
		x = or(x, p.and())
	}
	return x
}

// and parses a sequence of && expressions.
// On entry, the next input token has not yet been lexed.
// On exit, the next input token has been lexed and is in p.tok.
func (p *exprParser) and() Expr {
	x := p.not()
	for p.tok == "&&" {
		x = and(x, p.not())
	}
	return x
}

// not parses a ! expression.
// On entry, the next input token has not yet been lexed.
// On exit, the next input token has been lexed and is in p.tok.
func (p *exprParser) not() Expr {
	p.lex()
	if p.tok == "!" {
		p.lex()
		if p.tok == "!" {
			panic(&SyntaxError{Offset: p.pos, Err: "double negation not allowed"})
		}
		return not(p.atom())
	}
	return p.atom()
}

// atom parses a tag or a parenthesized expression.
// On entry, the next input token HAS been lexed.
// On exit, the next input token has been lexed and is in p.tok.
func (p *exprParser) atom() Expr {
	// first token already in p.tok
	if p.tok == "(" {
		pos := p.pos
		defer func() {
			if e := recover(); e != nil {
				if e, ok := e.(*SyntaxError); ok && e.Err == "unexpected end of expression" {
					e.Err = "missing close paren"
				}
				panic(e)
			}
		}()
		x := p.or()
		if p.tok != ")" {
			panic(&SyntaxError{Offset: pos, Err: "missing close paren"})
		}
		p.lex()
		return x
	}

	if !p.isTag {
		if p.tok == "" {
			panic(&SyntaxError{Offset: p.pos, Err: "unexpected end of expression"})
		}
		panic(&SyntaxError{Offset: p.pos, Err: "unexpected token " + p.tok})
	}
	tok := p.tok
	p.lex()
	return tag(tok)
}

// lex finds and consumes the next token in the input stream.
// On return, p.tok is set to the token text,
// p.isTag reports whether the token was a tag,
// and p.pos records the byte offset of the start of the token in the input stream.
// If lex reaches the end of the input, p.tok is set to the empty string.
// For any other syntax error, lex panics with a SyntaxError.
func (p *exprParser) lex() {
	p.isTag = false
	for p.i < len(p.s) && (p.s[p.i] == ' ' || p.s[p.i] == '\t') {
		p.i++
	}
	if p.i >= len(p.s) {
		p.tok = ""
		p.pos = p.i
		return
	}
	switch p.s[p.i] {
	case '(', ')', '!':
		p.pos = p.i
		p.i++
		p.tok = p.s[p.pos:p.i]
		return

	case '&', '|':
		if p.i+1 >= len(p.s) || p.s[p.i+1] != p.s[p.i] {
			panic(&SyntaxError{Offset: p.i, Err: "invalid syntax at " + string(rune(p.s[p.i]))})
		}
		p.pos = p.i
		p.i += 2
		p.tok = p.s[p.pos:p.i]
		return
	}

	tag := p.s[p.i:]
	for i, c := range tag {
		if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
			tag = tag[:i]
			break
		}
	}
	if tag == "" {
		c, _ := utf8.DecodeRuneInString(p.s[p.i:])
		panic(&SyntaxError{Offset: p.i, Err: "invalid syntax at " + string(c)})
	}

	p.pos = p.i
	p.i += len(tag)
	p.tok = p.s[p.pos:p.i]
	p.isTag = true
	return
}

// IsPlusBuild reports whether the line of text is a “// +build” constraint.
// It only checks the prefix of the text, not that the expression itself parses.
func IsPlusBuild(line string) bool {
	_, ok := splitPlusBuild(line)
	return ok
}

// splitGoBuild splits apart the leading //go:build prefix in line from the build expression itself.
// It returns "", false if the input is not a //go:build line or if the input contains multiple lines.
func splitPlusBuild(line string) (expr string, ok bool) {
	// A single trailing newline is OK; otherwise multiple lines are not.
	if len(line) > 0 && line[len(line)-1] == '\n' {
		line = line[:len(line)-1]
	}
	if strings.Contains(line, "\n") {
		return "", false
	}

	if !strings.HasPrefix(line, "//") {
		return "", false
	}
	line = line[len("//"):]
	// Note the space is optional; "//+build" is recognized too.
	line = strings.TrimSpace(line)

	if !strings.HasPrefix(line, "+build") {
		return "", false
	}
	line = line[len("+build"):]

	// If strings.TrimSpace finds more to trim after removing the +build prefix,
	// it means that the prefix was followed by a space, making this a +build line
	// (as opposed to a +buildsomethingelse line).
	// If line is empty, we had "// +build" by itself, which also counts.
	trim := strings.TrimSpace(line)
	if len(line) == len(trim) && line != "" {
		return "", false
	}

	return trim, true
}

// parsePlusBuildExpr parses a legacy build tag expression (as used with “// +build”).
func parsePlusBuildExpr(text string) Expr {
	var x Expr
	for _, clause := range strings.Fields(text) {
		var y Expr
		for _, lit := range strings.Split(clause, ",") {
			var z Expr
			var neg bool
			if strings.HasPrefix(lit, "!!") || lit == "!" {
				z = tag("ignore")
			} else {
				if strings.HasPrefix(lit, "!") {
					neg = true
					lit = lit[len("!"):]
				}
				if isValidTag(lit) {
					z = tag(lit)
				} else {
					z = tag("ignore")
				}
				if neg {
					z = not(z)
				}
			}
			if y == nil {
				y = z
			} else {
				y = and(y, z)
			}
		}
		if x == nil {
			x = y
		} else {
			x = or(x, y)
		}
	}
	return x
}

// isValidTag reports whether the word is a valid build tag.
// Tags must be letters, digits, underscores or dots.
// Unlike in Go identifiers, all digits are fine (e.g., "386").
func isValidTag(word string) bool {
	if word == "" {
		return false
	}
	for _, c := range word {
		if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
			return false
		}
	}
	return true
}

var errComplex = errors.New("expression too complex for // +build lines")

// PlusBuildLines returns a sequence of “// +build” lines that evaluate to the build expression x.
// If the expression is too complex to convert directly to “// +build” lines, PlusBuildLines returns an error.
func PlusBuildLines(x Expr) ([]string, error) {
	// Push all NOTs to the expression leaves, so that //go:build !(x && y) can be treated as !x || !y.
	// This rewrite is both efficient and commonly needed, so it's worth doing.
	// Essentially all other possible rewrites are too expensive and too rarely needed.
	x = pushNot(x, false)

	// Split into AND of ORs of ANDs of literals (tag or NOT tag).
	var split [][][]Expr
	for _, or := range appendSplitAnd(nil, x) {
		var ands [][]Expr
		for _, and := range appendSplitOr(nil, or) {
			var lits []Expr
			for _, lit := range appendSplitAnd(nil, and) {
				switch lit.(type) {
				case *TagExpr, *NotExpr:
					lits = append(lits, lit)
				default:
					return nil, errComplex
				}
			}
			ands = append(ands, lits)
		}
		split = append(split, ands)
	}

	// If all the ORs have length 1 (no actual OR'ing going on),
	// push the top-level ANDs to the bottom level, so that we get
	// one // +build line instead of many.
	maxOr := 0
	for _, or := range split {
		if maxOr < len(or) {
			maxOr = len(or)
		}
	}
	if maxOr == 1 {
		var lits []Expr
		for _, or := range split {
			lits = append(lits, or[0]...)
		}
		split = [][][]Expr{{lits}}
	}

	// Prepare the +build lines.
	var lines []string
	for _, or := range split {
		line := "// +build"
		for _, and := range or {
			clause := ""
			for i, lit := range and {
				if i > 0 {
					clause += ","
				}
				clause += lit.String()
			}
			line += " " + clause
		}
		lines = append(lines, line)
	}

	return lines, nil
}

// pushNot applies DeMorgan's law to push negations down the expression,
// so that only tags are negated in the result.
// (It applies the rewrites !(X && Y) => (!X || !Y) and !(X || Y) => (!X && !Y).)
func pushNot(x Expr, not bool) Expr {
	switch x := x.(type) {
	default:
		// unreachable
		return x
	case *NotExpr:
		if _, ok := x.X.(*TagExpr); ok && !not {
			return x
		}
		return pushNot(x.X, !not)
	case *TagExpr:
		if not {
			return &NotExpr{X: x}
		}
		return x
	case *AndExpr:
		x1 := pushNot(x.X, not)
		y1 := pushNot(x.Y, not)
		if not {
			return or(x1, y1)
		}
		if x1 == x.X && y1 == x.Y {
			return x
		}
		return and(x1, y1)
	case *OrExpr:
		x1 := pushNot(x.X, not)
		y1 := pushNot(x.Y, not)
		if not {
			return and(x1, y1)
		}
		if x1 == x.X && y1 == x.Y {
			return x
		}
		return or(x1, y1)
	}
}

// appendSplitAnd appends x to list while splitting apart any top-level && expressions.
// For example, appendSplitAnd({W}, X && Y && Z) = {W, X, Y, Z}.
func appendSplitAnd(list []Expr, x Expr) []Expr {
	if x, ok := x.(*AndExpr); ok {
		list = appendSplitAnd(list, x.X)
		list = appendSplitAnd(list, x.Y)
		return list
	}
	return append(list, x)
}

// appendSplitOr appends x to list while splitting apart any top-level || expressions.
// For example, appendSplitOr({W}, X || Y || Z) = {W, X, Y, Z}.
func appendSplitOr(list []Expr, x Expr) []Expr {
	if x, ok := x.(*OrExpr); ok {
		list = appendSplitOr(list, x.X)
		list = appendSplitOr(list, x.Y)
		return list
	}
	return append(list, x)
}
