// 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 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 are 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 []interface{} // the arguments for the note
}

// 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 FileSet 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(fset *token.FileSet, readFile ReadFile, end token.Pos, pattern interface{}) (token.Pos, token.Pos, error) {
	f := fset.File(end)
	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
}

func lineEnd(f *token.File, line int) token.Pos {
	if line >= f.LineCount() {
		return token.Pos(f.Base() + f.Size())
	}
	return f.LineStart(line + 1)
}
