// Copyright 2023 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 directive defines an Analyzer that checks known Go toolchain directives.
package directive

import (
	"go/ast"
	"go/parser"
	"go/token"
	"strings"
	"unicode"
	"unicode/utf8"

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

const Doc = `check Go toolchain directives such as //go:debug

This analyzer checks for problems with known Go toolchain directives
in all Go source files in a package directory, even those excluded by
//go:build constraints, and all non-Go source files too.

For //go:debug (see https://go.dev/doc/godebug), the analyzer checks
that the directives are placed only in Go source files, only above the
package comment, and only in package main or *_test.go files.

Support for other known directives may be added in the future.

This analyzer does not check //go:build, which is handled by the
buildtag analyzer.
`

var Analyzer = &analysis.Analyzer{
	Name: "directive",
	Doc:  Doc,
	URL:  "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/directive",
	Run:  runDirective,
}

func runDirective(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.
				continue
			}
			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) {
	check := newChecker(pass, pass.Fset.File(f.Package).Name(), f)

	for _, group := range f.Comments {
		// A +build comment is ignored after or adjoining the package declaration.
		if group.End()+1 >= f.Package {
			check.inHeader = 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.inHeader = false
		}

		// Check each line of a //-comment.
		for _, c := range group.List {
			check.comment(c.Slash, c.Text)
		}
	}
}

func checkOtherFile(pass *analysis.Pass, filename string) error {
	// We cannot use the Go parser, since is not a Go source file.
	// Read the raw bytes instead.
	content, tf, err := analysisutil.ReadFile(pass.Fset, filename)
	if err != nil {
		return err
	}

	check := newChecker(pass, filename, nil)
	check.nonGoFile(token.Pos(tf.Base()), string(content))
	return nil
}

type checker struct {
	pass     *analysis.Pass
	filename string
	file     *ast.File // nil for non-Go file
	inHeader bool      // in file header (before package declaration)
	inStar   bool      // currently in a /* */ comment
}

func newChecker(pass *analysis.Pass, filename string, file *ast.File) *checker {
	return &checker{
		pass:     pass,
		filename: filename,
		file:     file,
		inHeader: true,
	}
}

func (check *checker) nonGoFile(pos token.Pos, fullText string) {
	// Process each line.
	text := fullText
	inStar := false
	for text != "" {
		offset := len(fullText) - len(text)
		var line string
		line, text, _ = strings.Cut(text, "\n")

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

		// Skip over, cut out any /* */ comments,
		// to avoid being confused by a commented-out // comment.
		for {
			line = strings.TrimSpace(line)
			if inStar {
				var ok bool
				_, line, ok = strings.Cut(line, "*/")
				if !ok {
					break
				}
				inStar = false
				continue
			}
			line, inStar = stringsCutPrefix(line, "/*")
			if !inStar {
				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, line string) {
	if !strings.HasPrefix(line, "//go:") {
		return
	}
	// testing hack: stop at // ERROR
	if i := strings.Index(line, " // ERROR "); i >= 0 {
		line = line[:i]
	}

	verb := line
	if i := strings.IndexFunc(verb, unicode.IsSpace); i >= 0 {
		verb = verb[:i]
		if line[i] != ' ' && line[i] != '\t' && line[i] != '\n' {
			r, _ := utf8.DecodeRuneInString(line[i:])
			check.pass.Reportf(pos, "invalid space %#q in %s directive", r, verb)
		}
	}

	switch verb {
	default:
		// TODO: Use the go language version for the file.
		// If that version is not newer than us, then we can
		// report unknown directives.

	case "//go:build":
		// Ignore. The buildtag analyzer reports misplaced comments.

	case "//go:debug":
		if check.file == nil {
			check.pass.Reportf(pos, "//go:debug directive only valid in Go source files")
		} else if check.file.Name.Name != "main" && !strings.HasSuffix(check.filename, "_test.go") {
			check.pass.Reportf(pos, "//go:debug directive only valid in package main or test")
		} else if !check.inHeader {
			check.pass.Reportf(pos, "//go:debug directive only valid before package declaration")
		}
	}
}

// Go 1.20 strings.CutPrefix.
func stringsCutPrefix(s, prefix string) (after string, found bool) {
	if !strings.HasPrefix(s, prefix) {
		return s, false
	}
	return s[len(prefix):], true
}
