// Copyright 2018 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 expect provides support for interpreting structured comments in Go
source code (including go.mod and go.work files) as test expectations.

This is primarily intended for writing tests of things that process Go source
files, although it does not directly depend on the testing package.

Collect notes with the Extract or Parse functions, and use the
MatchBefore function to find matches within the lines the comments were on.

The interpretation of the notes depends on the application.
For example, the test suite for a static checking tool might
use a @diag note to indicate an expected diagnostic:

	fmt.Printf("%s", 1) //@ diag("%s wants a string, got int")

By contrast, the test suite for a source code navigation tool
might use notes to indicate the positions of features of
interest, the actions to be performed by the test,
and their expected outcomes:

	var x = 1 //@ x_decl
	...
	print(x) //@ definition("x", x_decl)
	print(x) //@ typeof("x", "int")

# Note comment syntax

Note comments always start with the special marker @, which must be the
very first character after the comment opening pair, so //@ or /*@ with no
spaces.

This is followed by a comma separated list of notes.

A note always starts with an identifier, which is optionally followed by an
argument list. The argument list is surrounded with parentheses and contains a
comma-separated list of arguments.
The empty parameter list and the missing parameter list are distinguishable if
needed; they result in a nil or an empty list in the Args parameter respectively.

Arguments may be positional, such as f(value), or named, such as f(name=value).
Positional arguments must appear before named arguments.
Names may not be repeated.

Argument values may be either identifiers or literals.
The literals supported are the basic value literals, of string, float, integer
true, false or nil. All the literals match the standard go conventions, with
all bases of integers, and both quote and backtick strings.
There is one extra literal type, which is a string literal preceded by the
identifier "re" which is compiled to a regular expression.
*/
package expect

import (
	"bytes"
	"fmt"
	"go/token"
	"regexp"
)

// Note is a parsed note from an expect comment.
// It knows the position of the start of the comment, and the name and
// arguments that make up the note.
type Note struct {
	Pos       token.Pos      // The position at which the note identifier appears
	Name      string         // the name associated with the note
	Args      []any          // positional arguments (non-nil if parens were present)
	NamedArgs map[string]any // named arguments (or nil if none)
}

// ReadFile is the type of a function that can provide file contents for a
// given filename.
// This is used in MatchBefore to look up the content of the file in order to
// find the line to match the pattern against.
type ReadFile func(filename string) ([]byte, error)

// MatchBefore attempts to match a pattern in the line before the supplied pos.
// It uses the token.File and the ReadFile to work out the contents of the line
// that end is part of, and then matches the pattern against the content of the
// start of that line up to the supplied position.
// The pattern may be either a simple string, []byte or a *regexp.Regexp.
// MatchBefore returns the range of the line that matched the pattern, and
// invalid positions if there was no match, or an error if the line could not be
// found.
func MatchBefore(f *token.File, readFile ReadFile, end token.Pos, pattern any) (token.Pos, token.Pos, error) {
	content, err := readFile(f.Name())
	if err != nil {
		return token.NoPos, token.NoPos, fmt.Errorf("invalid file: %v", err)
	}
	position := f.Position(end)
	startOffset := f.Offset(f.LineStart(position.Line))
	endOffset := f.Offset(end)
	line := content[startOffset:endOffset]
	matchStart, matchEnd := -1, -1
	switch pattern := pattern.(type) {
	case string:
		bytePattern := []byte(pattern)
		matchStart = bytes.Index(line, bytePattern)
		if matchStart >= 0 {
			matchEnd = matchStart + len(bytePattern)
		}
	case []byte:
		matchStart = bytes.Index(line, pattern)
		if matchStart >= 0 {
			matchEnd = matchStart + len(pattern)
		}
	case *regexp.Regexp:
		match := pattern.FindIndex(line)
		if len(match) > 0 {
			matchStart = match[0]
			matchEnd = match[1]
		}
	}
	if matchStart < 0 {
		return token.NoPos, token.NoPos, nil
	}
	return f.Pos(startOffset + matchStart), f.Pos(startOffset + matchEnd), nil
}
