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

package main_test

// This file defines a test framework for guru queries.
//
// The files beneath testdata/src contain Go programs containing
// query annotations of the form:
//
//   @verb id "select"
//
// where verb is the query mode (e.g. "callers"), id is a unique name
// for this query, and "select" is a regular expression matching the
// substring of the current line that is the query's input selection.
//
// The expected output for each query is provided in the accompanying
// .golden file.
//
// (Location information is not included because it's too fragile to
// display as text.  TODO(adonovan): think about how we can test its
// correctness, since it is critical information.)
//
// Run this test with:
// 	% go test golang.org/x/tools/cmd/guru -update
// to update the golden files.

import (
	"bytes"
	"flag"
	"fmt"
	"go/build"
	"go/parser"
	"go/token"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"sort"
	"strconv"
	"strings"
	"sync"
	"testing"

	guru "golang.org/x/tools/cmd/guru"
)

var updateFlag = flag.Bool("update", false, "Update the golden files.")

type query struct {
	id       string         // unique id
	verb     string         // query mode, e.g. "callees"
	posn     token.Position // query position
	filename string
	queryPos string // query position in command-line syntax
}

func parseRegexp(text string) (*regexp.Regexp, error) {
	pattern, err := strconv.Unquote(text)
	if err != nil {
		return nil, fmt.Errorf("can't unquote %s", text)
	}
	return regexp.Compile(pattern)
}

// parseQueries parses and returns the queries in the named file.
func parseQueries(t *testing.T, filename string) []*query {
	filedata, err := ioutil.ReadFile(filename)
	if err != nil {
		t.Fatal(err)
	}

	// Parse the file once to discover the test queries.
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, filename, filedata, parser.ParseComments)
	if err != nil {
		t.Fatal(err)
	}

	lines := bytes.Split(filedata, []byte("\n"))

	var queries []*query
	queriesById := make(map[string]*query)

	// Find all annotations of these forms:
	expectRe := regexp.MustCompile(`@([a-z]+)\s+(\S+)\s+(\".*)$`) // @verb id "regexp"
	for _, c := range f.Comments {
		text := strings.TrimSpace(c.Text())
		if text == "" || text[0] != '@' {
			continue
		}
		posn := fset.Position(c.Pos())

		// @verb id "regexp"
		match := expectRe.FindStringSubmatch(text)
		if match == nil {
			t.Errorf("%s: ill-formed query: %s", posn, text)
			continue
		}

		id := match[2]
		if prev, ok := queriesById[id]; ok {
			t.Errorf("%s: duplicate id %s", posn, id)
			t.Errorf("%s: previously used here", prev.posn)
			continue
		}

		q := &query{
			id:       id,
			verb:     match[1],
			filename: filename,
			posn:     posn,
		}

		if match[3] != `"nopos"` {
			selectRe, err := parseRegexp(match[3])
			if err != nil {
				t.Errorf("%s: %s", posn, err)
				continue
			}

			// Find text of the current line, sans query.
			// (Queries must be // not /**/ comments.)
			line := lines[posn.Line-1][:posn.Column-1]

			// Apply regexp to current line to find input selection.
			loc := selectRe.FindIndex(line)
			if loc == nil {
				t.Errorf("%s: selection pattern %s doesn't match line %q",
					posn, match[3], string(line))
				continue
			}

			// Assumes ASCII. TODO(adonovan): test on UTF-8.
			linestart := posn.Offset - (posn.Column - 1)

			// Compute the file offsets.
			q.queryPos = fmt.Sprintf("%s:#%d,#%d",
				filename, linestart+loc[0], linestart+loc[1])
		}

		queries = append(queries, q)
		queriesById[id] = q
	}

	// Return the slice, not map, for deterministic iteration.
	return queries
}

// doQuery poses query q to the guru and writes its response and
// error (if any) to out.
func doQuery(out io.Writer, q *query, json bool) {
	fmt.Fprintf(out, "-------- @%s %s --------\n", q.verb, q.id)

	var buildContext = build.Default
	buildContext.GOPATH = "testdata"
	pkg := filepath.Dir(strings.TrimPrefix(q.filename, "testdata/src/"))

	gopathAbs, _ := filepath.Abs(buildContext.GOPATH)

	var outputMu sync.Mutex // guards outputs
	var outputs []string    // JSON objects or lines of text
	outputFn := func(fset *token.FileSet, qr guru.QueryResult) {
		outputMu.Lock()
		defer outputMu.Unlock()
		if json {
			jsonstr := string(qr.JSON(fset))
			// Sanitize any absolute filenames that creep in.
			jsonstr = strings.Replace(jsonstr, gopathAbs, "$GOPATH", -1)
			outputs = append(outputs, jsonstr)
		} else {
			// suppress position information
			qr.PrintPlain(func(_ interface{}, format string, args ...interface{}) {
				outputs = append(outputs, fmt.Sprintf(format, args...))
			})
		}
	}

	query := guru.Query{
		Pos:        q.queryPos,
		Build:      &buildContext,
		Scope:      []string{pkg},
		Reflection: true,
		Output:     outputFn,
	}

	if err := guru.Run(q.verb, &query); err != nil {
		fmt.Fprintf(out, "\nError: %s\n", err)
		return
	}

	// In a "referrers" query, references are sorted within each
	// package but packages are visited in arbitrary order,
	// so for determinism we sort them.  Line 0 is a caption.
	if q.verb == "referrers" {
		sort.Strings(outputs[1:])
	}

	for _, output := range outputs {
		fmt.Fprintf(out, "%s\n", output)
	}

	if !json {
		io.WriteString(out, "\n")
	}
}

func TestGuru(t *testing.T) {
	switch runtime.GOOS {
	case "android":
		t.Skipf("skipping test on %q (no testdata dir)", runtime.GOOS)
	case "windows":
		t.Skipf("skipping test on %q (no /usr/bin/diff)", runtime.GOOS)
	}

	for _, filename := range []string{
		"testdata/src/alias/alias.go", // iff guru.HasAlias (go1.9)
		"testdata/src/calls/main.go",
		"testdata/src/describe/main.go",
		"testdata/src/describe/main19.go", // iff go1.9
		"testdata/src/freevars/main.go",
		"testdata/src/implements/main.go",
		"testdata/src/implements-methods/main.go",
		"testdata/src/imports/main.go",
		"testdata/src/peers/main.go",
		"testdata/src/pointsto/main.go",
		"testdata/src/referrers/main.go",
		"testdata/src/reflection/main.go",
		"testdata/src/what/main.go",
		"testdata/src/whicherrs/main.go",
		"testdata/src/softerrs/main.go",
		// JSON:
		// TODO(adonovan): most of these are very similar; combine them.
		"testdata/src/calls-json/main.go",
		"testdata/src/peers-json/main.go",
		"testdata/src/definition-json/main.go",
		"testdata/src/definition-json/main19.go",
		"testdata/src/describe-json/main.go",
		"testdata/src/implements-json/main.go",
		"testdata/src/implements-methods-json/main.go",
		"testdata/src/pointsto-json/main.go",
		"testdata/src/referrers-json/main.go",
		"testdata/src/what-json/main.go",
	} {
		filename := filename
		name := strings.Split(filename, "/")[2]
		t.Run(name, func(t *testing.T) {
			t.Parallel()
			if filename == "testdata/src/referrers/main.go" && runtime.GOOS == "plan9" {
				// Disable this test on plan9 since it expects a particular
				// wording for a "no such file or directory" error.
				t.Skip()
			}
			if filename == "testdata/src/alias/alias.go" && !guru.HasAlias {
				t.Skip()
			}
			if strings.HasSuffix(filename, "19.go") && !contains(build.Default.ReleaseTags, "go1.9") {
				// TODO(adonovan): recombine the 'describe' and 'definition'
				// tests once we drop support for go1.8.
				t.Skip()
			}
			if filename == "testdata/src/referrers/main.go" && !contains(build.Default.ReleaseTags, "go1.11") {
				// Disabling broken test on Go 1.9 and Go 1.10. https://golang.org/issue/24421
				// TODO(gri,adonovan): fix this test.
				t.Skip()
			}

			json := strings.Contains(filename, "-json/")
			queries := parseQueries(t, filename)
			golden := filename + "lden"
			got := filename + "t"
			gotfh, err := os.Create(got)
			if err != nil {
				t.Fatalf("Create(%s) failed: %s", got, err)
			}
			defer os.Remove(got)
			defer gotfh.Close()

			// Run the guru on each query, redirecting its output
			// and error (if any) to the foo.got file.
			for _, q := range queries {
				doQuery(gotfh, q, json)
			}

			// Compare foo.got with foo.golden.
			var cmd *exec.Cmd
			switch runtime.GOOS {
			case "plan9":
				cmd = exec.Command("/bin/diff", "-c", golden, got)
			default:
				cmd = exec.Command("/usr/bin/diff", "-u", golden, got)
			}
			buf := new(bytes.Buffer)
			cmd.Stdout = buf
			cmd.Stderr = os.Stderr
			if err := cmd.Run(); err != nil {
				t.Errorf("Guru tests for %s failed: %s.\n%s\n",
					filename, err, buf)

				if *updateFlag {
					t.Logf("Updating %s...", golden)
					if err := exec.Command("/bin/cp", got, golden).Run(); err != nil {
						t.Errorf("Update failed: %s", err)
					}
				}
			}
		})
	}
}

func contains(haystack []string, needle string) bool {
	for _, x := range haystack {
		if needle == x {
			return true
		}
	}
	return false
}

func TestIssue14684(t *testing.T) {
	var buildContext = build.Default
	buildContext.GOPATH = "testdata"
	query := guru.Query{
		Pos:   "testdata/src/README.txt:#1",
		Build: &buildContext,
	}
	err := guru.Run("freevars", &query)
	if err == nil {
		t.Fatal("guru query succeeded unexpectedly")
	}
	if got, want := err.Error(), "testdata/src/README.txt is not a Go source file"; got != want {
		t.Errorf("query error was %q, want %q", got, want)
	}
}
