// 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 //go:build and // +build directives"

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
	}
}
