// Copyright 2013 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.

//go:build go1.16
// +build go1.16

// Package buildtag defines an Analyzer that checks build tags.
package buildtag

import (
	"go/ast"
	"go/build/constraint"
	"go/parser"
	"go/token"
	"strings"
	"unicode"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
)

const Doc = "check that +build tags are well-formed and correctly located"

var Analyzer = &analysis.Analyzer{
	Name: "buildtag",
	Doc:  Doc,
	Run:  runBuildTag,
}

func runBuildTag(pass *analysis.Pass) (interface{}, error) {
	for _, f := range pass.Files {
		checkGoFile(pass, f)
	}
	for _, name := range pass.OtherFiles {
		if err := checkOtherFile(pass, name); err != nil {
			return nil, err
		}
	}
	for _, name := range pass.IgnoredFiles {
		if strings.HasSuffix(name, ".go") {
			f, err := parser.ParseFile(pass.Fset, name, nil, parser.ParseComments)
			if err != nil {
				// Not valid Go source code - not our job to diagnose, so ignore.
				return nil, nil
			}
			checkGoFile(pass, f)
		} else {
			if err := checkOtherFile(pass, name); err != nil {
				return nil, err
			}
		}
	}
	return nil, nil
}

func checkGoFile(pass *analysis.Pass, f *ast.File) {
	var check checker
	check.init(pass)
	defer check.finish()

	for _, group := range f.Comments {
		// A +build comment is ignored after or adjoining the package declaration.
		if group.End()+1 >= f.Package {
			check.plusBuildOK = false
		}
		// A //go:build comment is ignored after the package declaration
		// (but adjoining it is OK, in contrast to +build comments).
		if group.Pos() >= f.Package {
			check.goBuildOK = false
		}

		// Check each line of a //-comment.
		for _, c := range group.List {
			// "+build" is ignored within or after a /*...*/ comment.
			if !strings.HasPrefix(c.Text, "//") {
				check.plusBuildOK = false
			}
			check.comment(c.Slash, c.Text)
		}
	}
}

func checkOtherFile(pass *analysis.Pass, filename string) error {
	var check checker
	check.init(pass)
	defer check.finish()

	// We cannot use the Go parser, since this may not be a Go source file.
	// Read the raw bytes instead.
	content, tf, err := analysisutil.ReadFile(pass.Fset, filename)
	if err != nil {
		return err
	}

	check.file(token.Pos(tf.Base()), string(content))
	return nil
}

type checker struct {
	pass         *analysis.Pass
	plusBuildOK  bool            // "+build" lines still OK
	goBuildOK    bool            // "go:build" lines still OK
	crossCheck   bool            // cross-check go:build and +build lines when done reading file
	inStar       bool            // currently in a /* */ comment
	goBuildPos   token.Pos       // position of first go:build line found
	plusBuildPos token.Pos       // position of first "+build" line found
	goBuild      constraint.Expr // go:build constraint found
	plusBuild    constraint.Expr // AND of +build constraints found
}

func (check *checker) init(pass *analysis.Pass) {
	check.pass = pass
	check.goBuildOK = true
	check.plusBuildOK = true
	check.crossCheck = true
}

func (check *checker) file(pos token.Pos, text string) {
	// Determine cutpoint where +build comments are no longer valid.
	// They are valid in leading // comments in the file followed by
	// a blank line.
	//
	// This must be done as a separate pass because of the
	// requirement that the comment be followed by a blank line.
	var plusBuildCutoff int
	fullText := text
	for text != "" {
		i := strings.Index(text, "\n")
		if i < 0 {
			i = len(text)
		} else {
			i++
		}
		offset := len(fullText) - len(text)
		line := text[:i]
		text = text[i:]
		line = strings.TrimSpace(line)
		if !strings.HasPrefix(line, "//") && line != "" {
			break
		}
		if line == "" {
			plusBuildCutoff = offset
		}
	}

	// Process each line.
	// Must stop once we hit goBuildOK == false
	text = fullText
	check.inStar = false
	for text != "" {
		i := strings.Index(text, "\n")
		if i < 0 {
			i = len(text)
		} else {
			i++
		}
		offset := len(fullText) - len(text)
		line := text[:i]
		text = text[i:]
		check.plusBuildOK = offset < plusBuildCutoff

		if strings.HasPrefix(line, "//") {
			check.comment(pos+token.Pos(offset), line)
			continue
		}

		// Keep looking for the point at which //go:build comments
		// stop being allowed. Skip over, cut out any /* */ comments.
		for {
			line = strings.TrimSpace(line)
			if check.inStar {
				i := strings.Index(line, "*/")
				if i < 0 {
					line = ""
					break
				}
				line = line[i+len("*/"):]
				check.inStar = false
				continue
			}
			if strings.HasPrefix(line, "/*") {
				check.inStar = true
				line = line[len("/*"):]
				continue
			}
			break
		}
		if line != "" {
			// Found non-comment non-blank line.
			// Ends space for valid //go:build comments,
			// but also ends the fraction of the file we can
			// reliably parse. From this point on we might
			// incorrectly flag "comments" inside multiline
			// string constants or anything else (this might
			// not even be a Go program). So stop.
			break
		}
	}
}

func (check *checker) comment(pos token.Pos, text string) {
	if strings.HasPrefix(text, "//") {
		if strings.Contains(text, "+build") {
			check.plusBuildLine(pos, text)
		}
		if strings.Contains(text, "//go:build") {
			check.goBuildLine(pos, text)
		}
	}
	if strings.HasPrefix(text, "/*") {
		if i := strings.Index(text, "\n"); i >= 0 {
			// multiline /* */ comment - process interior lines
			check.inStar = true
			i++
			pos += token.Pos(i)
			text = text[i:]
			for text != "" {
				i := strings.Index(text, "\n")
				if i < 0 {
					i = len(text)
				} else {
					i++
				}
				line := text[:i]
				if strings.HasPrefix(line, "//") {
					check.comment(pos, line)
				}
				pos += token.Pos(i)
				text = text[i:]
			}
			check.inStar = false
		}
	}
}

func (check *checker) goBuildLine(pos token.Pos, line string) {
	if !constraint.IsGoBuild(line) {
		if !strings.HasPrefix(line, "//go:build") && constraint.IsGoBuild("//"+strings.TrimSpace(line[len("//"):])) {
			check.pass.Reportf(pos, "malformed //go:build line (space between // and go:build)")
		}
		return
	}
	if !check.goBuildOK || check.inStar {
		check.pass.Reportf(pos, "misplaced //go:build comment")
		check.crossCheck = false
		return
	}

	if check.goBuildPos == token.NoPos {
		check.goBuildPos = pos
	} else {
		check.pass.Reportf(pos, "unexpected extra //go:build line")
		check.crossCheck = false
	}

	// testing hack: stop at // ERROR
	if i := strings.Index(line, " // ERROR "); i >= 0 {
		line = line[:i]
	}

	x, err := constraint.Parse(line)
	if err != nil {
		check.pass.Reportf(pos, "%v", err)
		check.crossCheck = false
		return
	}

	if check.goBuild == nil {
		check.goBuild = x
	}
}

func (check *checker) plusBuildLine(pos token.Pos, line string) {
	line = strings.TrimSpace(line)
	if !constraint.IsPlusBuild(line) {
		// Comment with +build but not at beginning.
		// Only report early in file.
		if check.plusBuildOK && !strings.HasPrefix(line, "// want") {
			check.pass.Reportf(pos, "possible malformed +build comment")
		}
		return
	}
	if !check.plusBuildOK { // inStar implies !plusBuildOK
		check.pass.Reportf(pos, "misplaced +build comment")
		check.crossCheck = false
	}

	if check.plusBuildPos == token.NoPos {
		check.plusBuildPos = pos
	}

	// testing hack: stop at // ERROR
	if i := strings.Index(line, " // ERROR "); i >= 0 {
		line = line[:i]
	}

	fields := strings.Fields(line[len("//"):])
	// IsPlusBuildConstraint check above implies fields[0] == "+build"
	for _, arg := range fields[1:] {
		for _, elem := range strings.Split(arg, ",") {
			if strings.HasPrefix(elem, "!!") {
				check.pass.Reportf(pos, "invalid double negative in build constraint: %s", arg)
				check.crossCheck = false
				continue
			}
			elem = strings.TrimPrefix(elem, "!")
			for _, c := range elem {
				if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
					check.pass.Reportf(pos, "invalid non-alphanumeric build constraint: %s", arg)
					check.crossCheck = false
					break
				}
			}
		}
	}

	if check.crossCheck {
		y, err := constraint.Parse(line)
		if err != nil {
			// Should never happen - constraint.Parse never rejects a // +build line.
			// Also, we just checked the syntax above.
			// Even so, report.
			check.pass.Reportf(pos, "%v", err)
			check.crossCheck = false
			return
		}
		if check.plusBuild == nil {
			check.plusBuild = y
		} else {
			check.plusBuild = &constraint.AndExpr{X: check.plusBuild, Y: y}
		}
	}
}

func (check *checker) finish() {
	if !check.crossCheck || check.plusBuildPos == token.NoPos || check.goBuildPos == token.NoPos {
		return
	}

	// Have both //go:build and // +build,
	// with no errors found (crossCheck still true).
	// Check they match.
	var want constraint.Expr
	lines, err := constraint.PlusBuildLines(check.goBuild)
	if err != nil {
		check.pass.Reportf(check.goBuildPos, "%v", err)
		return
	}
	for _, line := range lines {
		y, err := constraint.Parse(line)
		if err != nil {
			// Definitely should not happen, but not the user's fault.
			// Do not report.
			return
		}
		if want == nil {
			want = y
		} else {
			want = &constraint.AndExpr{X: want, Y: y}
		}
	}
	if want.String() != check.plusBuild.String() {
		check.pass.Reportf(check.plusBuildPos, "+build lines do not match //go:build condition")
		return
	}
}
