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

// This test uses 'expectation' comments embedded within testdata/*.go
// files to specify the expected pointer analysis behaviour.
// See below for grammar.

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"io/ioutil"
	"os"
	"regexp"
	"strconv"
	"strings"
	"testing"

	"code.google.com/p/go.tools/go/types"
	"code.google.com/p/go.tools/go/types/typemap"
	"code.google.com/p/go.tools/importer"
	"code.google.com/p/go.tools/pointer"
	"code.google.com/p/go.tools/ssa"
)

var inputs = []string{
	// Currently debugging:
	// "testdata/tmp.go",

	// Working:
	"testdata/another.go",
	"testdata/arrays.go",
	"testdata/channels.go",
	"testdata/context.go",
	"testdata/conv.go",
	"testdata/flow.go",
	"testdata/fmtexcerpt.go",
	"testdata/func.go",
	"testdata/hello.go",
	"testdata/interfaces.go",
	"testdata/maps.go",
	"testdata/panic.go",
	"testdata/recur.go",
	"testdata/structs.go",
	"testdata/a_test.go",

	// TODO(adonovan): get these tests (of reflection) passing.
	// (The tests are mostly sound since they were used for a
	// previous implementation.)
	// "testdata/funcreflect.go",
	// "testdata/arrayreflect.go",
	// "testdata/chanreflect.go",
	// "testdata/finalizer.go",
	// "testdata/reflect.go",
	// "testdata/mapreflect.go",
	// "testdata/structreflect.go",
}

// Expectation grammar:
//
// @calls f -> g
//
//   A 'calls' expectation asserts that edge (f, g) appears in the
//   callgraph.  f and g are notated as per Function.String(), which
//   may contain spaces (e.g. promoted method in anon struct).
//
// @pointsto a | b | c
//
//   A 'pointsto' expectation asserts that the points-to set of its
//   operand contains exactly the set of labels {a,b,c} notated as per
//   labelString.
//
//   A 'pointsto' expectation must appear on the same line as a
//   print(x) statement; the expectation's operand is x.
//
//   If one of the strings is "...", the expectation asserts that the
//   points-to set at least the other labels.
//
//   We use '|' because label names may contain spaces, e.g.  methods
//   of anonymous structs.
//
//   From a theoretical perspective, concrete types in interfaces are
//   labels too, but they are represented differently and so have a
//   different expectation, @concrete, below.
//
// @concrete t | u | v
//
//   A 'concrete' expectation asserts that the set of possible dynamic
//   types of its interface operand is exactly {t,u,v}, notated per
//   go/types.Type.String(). In other words, it asserts that the type
//   component of the interface may point to that set of concrete type
//   literals.
//
//   A 'concrete' expectation must appear on the same line as a
//   print(x) statement; the expectation's operand is x.
//
//   If one of the strings is "...", the expectation asserts that the
//   interface's type may point to at least the  other concrete types.
//
//   We use '|' because type names may contain spaces.
//
// @warning "regexp"
//
//   A 'warning' expectation asserts that the analysis issues a
//   warning that matches the regular expression within the string
//   literal.
//
// @line id
//
//   A line directive associates the name "id" with the current
//   file:line.  The string form of labels will use this id instead of
//   a file:line, making @pointsto expectations more robust against
//   perturbations in the source file.
//   (NB, anon functions still include line numbers.)
//
type expectation struct {
	kind     string // "pointsto" | "concrete" | "calls" | "warning"
	filename string
	linenum  int // source line number, 1-based
	args     []string
	types    []types.Type // for concrete
}

func (e *expectation) String() string {
	return fmt.Sprintf("@%s[%s]", e.kind, strings.Join(e.args, " | "))
}

func (e *expectation) errorf(format string, args ...interface{}) {
	fmt.Printf("%s:%d: ", e.filename, e.linenum)
	fmt.Printf(format, args...)
	fmt.Println()
}

func (e *expectation) needsProbe() bool {
	return e.kind == "pointsto" || e.kind == "concrete"
}

// A record of a call to the built-in print() function.  Used for testing.
type probe struct {
	instr *ssa.CallCommon
	arg0  pointer.Pointer // first argument to print
}

// Find probe (call to print(x)) of same source
// file/line as expectation.
func findProbe(prog *ssa.Program, probes []probe, e *expectation) *probe {
	for _, p := range probes {
		pos := prog.Fset.Position(p.instr.Pos())
		if pos.Line == e.linenum && pos.Filename == e.filename {
			// TODO(adonovan): send this to test log (display only on failure).
			// fmt.Printf("%s:%d: info: found probe for %s: %s\n",
			// 	e.filename, e.linenum, e, p.arg0) // debugging
			return &p
		}
	}
	return nil // e.g. analysis didn't reach this call
}

func doOneInput(input, filename string) bool {
	impctx := &importer.Config{Loader: importer.MakeGoBuildLoader(nil)}
	imp := importer.New(impctx)

	// Parsing.
	f, err := parser.ParseFile(imp.Fset, filename, input, parser.DeclarationErrors)
	if err != nil {
		// TODO(adonovan): err is a scanner error list;
		// display all errors not just first?
		fmt.Println(err.Error())
		return false
	}

	// Type checking.
	info := imp.CreateSourcePackage("main", []*ast.File{f})
	if info.Err != nil {
		fmt.Println(info.Err.Error())
		return false
	}

	// SSA creation + building.
	prog := ssa.NewProgram(imp.Fset, ssa.SanityCheckFunctions)
	for _, info := range imp.Packages {
		prog.CreatePackage(info)
	}
	prog.BuildAll()

	mainpkg := prog.Package(info.Pkg)
	ptrmain := mainpkg // main package for the pointer analysis
	if mainpkg.Func("main") == nil {
		// No main function; assume it's a test.
		mainpkg.CreateTestMainFunction()
		fmt.Printf("%s: synthesized testmain package for test.\n", imp.Fset.Position(f.Package))
	}

	ok := true

	lineMapping := make(map[string]string) // maps "file:line" to @line tag

	// Parse expectations in this input.
	var exps []*expectation
	re := regexp.MustCompile("// *@([a-z]*) *(.*)$")
	lines := strings.Split(input, "\n")
	for linenum, line := range lines {
		linenum++ // make it 1-based
		if matches := re.FindAllStringSubmatch(line, -1); matches != nil {
			match := matches[0]
			kind, rest := match[1], match[2]
			e := &expectation{kind: kind, filename: filename, linenum: linenum}

			if kind == "line" {
				if rest == "" {
					ok = false
					e.errorf("@%s expectation requires identifier", kind)
				} else {
					lineMapping[fmt.Sprintf("%s:%d", filename, linenum)] = rest
				}
				continue
			}

			if e.needsProbe() && !strings.Contains(line, "print(") {
				ok = false
				e.errorf("@%s expectation must follow call to print(x)", kind)
				continue
			}

			switch kind {
			case "pointsto":
				e.args = split(rest, "|")

			case "concrete":
				for _, typstr := range split(rest, "|") {
					var t types.Type = types.Typ[types.Invalid] // means "..."
					if typstr != "..." {
						texpr, err := parser.ParseExpr(typstr)
						if err != nil {
							ok = false
							// Don't print err since its location is bad.
							e.errorf("'%s' is not a valid type", typstr)
							continue
						}
						t, _, err = types.EvalNode(imp.Fset, texpr, mainpkg.Object, mainpkg.Object.Scope())
						if err != nil {
							ok = false
							// TODO Don't print err since its location is bad.
							e.errorf("'%s' is not a valid type: %s", typstr, err)
							continue
						}
					}
					e.types = append(e.types, t)
				}

			case "calls":
				e.args = split(rest, "->")
				// TODO(adonovan): eagerly reject the
				// expectation if fn doesn't denote
				// existing function, rather than fail
				// the expectation after analysis.
				if len(e.args) != 2 {
					ok = false
					e.errorf("@calls expectation wants 'caller -> callee' arguments")
					continue
				}

			case "warning":
				lit, err := strconv.Unquote(strings.TrimSpace(rest))
				if err != nil {
					ok = false
					e.errorf("couldn't parse @warning operand: %s", err.Error())
					continue
				}
				e.args = append(e.args, lit)

			default:
				ok = false
				e.errorf("unknown expectation kind: %s", e)
				continue
			}
			exps = append(exps, e)
		}
	}

	var probes []probe
	var warnings []string
	var log bytes.Buffer

	callgraph := make(pointer.CallGraph)

	// Run the analysis.
	config := &pointer.Config{
		Mains: []*ssa.Package{ptrmain},
		Log:   &log,
		Print: func(site *ssa.CallCommon, p pointer.Pointer) {
			probes = append(probes, probe{site, p})
		},
		Call: callgraph.AddEdge,
		Warn: func(pos token.Pos, format string, args ...interface{}) {
			msg := fmt.Sprintf(format, args...)
			fmt.Printf("%s: warning: %s\n", prog.Fset.Position(pos), msg)
			warnings = append(warnings, msg)
		},
	}
	pointer.Analyze(config)

	// Print the log is there was an error or a panic.
	complete := false
	defer func() {
		if !complete || !ok {
			log.WriteTo(os.Stderr)
		}
	}()

	// Check the expectations.
	for _, e := range exps {
		var pr *probe
		if e.needsProbe() {
			if pr = findProbe(prog, probes, e); pr == nil {
				ok = false
				e.errorf("unreachable print() statement has expectation %s", e)
				continue
			}
			if pr.arg0 == nil {
				ok = false
				e.errorf("expectation on non-pointerlike operand: %s", pr.instr.Args[0].Type())
				continue
			}
		}

		switch e.kind {
		case "pointsto":
			if !checkPointsToExpectation(e, pr, lineMapping, prog) {
				ok = false
			}

		case "concrete":
			if !checkConcreteExpectation(e, pr) {
				ok = false
			}

		case "calls":
			if !checkCallsExpectation(prog, e, callgraph) {
				ok = false
			}

		case "warning":
			if !checkWarningExpectation(prog, e, warnings) {
				ok = false
			}
		}
	}

	complete = true

	// ok = false // debugging: uncomment to always see log

	return ok
}

func labelString(l *pointer.Label, lineMapping map[string]string, prog *ssa.Program) string {
	// Functions and Globals need no pos suffix.
	switch l.Value.(type) {
	case *ssa.Function, *ssa.Global:
		return l.String()
	}

	str := l.String()
	if pos := l.Value.Pos(); pos != 0 {
		// Append the position, using a @line tag instead of a line number, if defined.
		posn := prog.Fset.Position(l.Value.Pos())
		s := fmt.Sprintf("%s:%d", posn.Filename, posn.Line)
		if tag, ok := lineMapping[s]; ok {
			return fmt.Sprintf("%s@%s:%d", str, tag, posn.Column)
		}
		str = fmt.Sprintf("%s@%s", str, posn)
	}
	return str
}

func checkPointsToExpectation(e *expectation, pr *probe, lineMapping map[string]string, prog *ssa.Program) bool {
	expected := make(map[string]struct{})
	surplus := make(map[string]struct{})
	exact := true
	for _, g := range e.args {
		if g == "..." {
			exact = false
			continue
		}
		expected[g] = struct{}{}
	}
	// Find the set of labels that the probe's
	// argument (x in print(x)) may point to.
	for _, label := range pr.arg0.PointsTo().Labels() {
		name := labelString(label, lineMapping, prog)
		if _, ok := expected[name]; ok {
			delete(expected, name)
		} else if exact {
			surplus[name] = struct{}{}
		}
	}
	// Report set difference:
	ok := true
	if len(expected) > 0 {
		ok = false
		e.errorf("value does not alias these expected labels: %s", join(expected))
	}
	if len(surplus) > 0 {
		ok = false
		e.errorf("value may additionally alias these labels: %s", join(surplus))
	}
	return ok
}

// underlying returns the underlying type of typ.  Copied from go/types.
func underlyingType(typ types.Type) types.Type {
	if typ, ok := typ.(*types.Named); ok {
		return typ.Underlying() // underlying types are never NamedTypes
	}
	if typ == nil {
		panic("underlying(nil)")
	}
	return typ
}

func checkConcreteExpectation(e *expectation, pr *probe) bool {
	var expected typemap.M
	var surplus typemap.M
	exact := true
	for _, g := range e.types {
		if g == types.Typ[types.Invalid] {
			exact = false
			continue
		}
		expected.Set(g, struct{}{})
	}

	switch t := underlyingType(pr.instr.Args[0].Type()).(type) {
	case *types.Interface:
		// ok
	default:
		e.errorf("@concrete expectation requires an interface-typed operand, got %s", t)
		return false
	}

	// Find the set of concrete types that the probe's
	// argument (x in print(x)) may contain.
	for _, conc := range pr.arg0.PointsTo().ConcreteTypes().Keys() {
		if expected.At(conc) != nil {
			expected.Delete(conc)
		} else if exact {
			surplus.Set(conc, struct{}{})
		}
	}
	// Report set difference:
	ok := true
	if expected.Len() > 0 {
		ok = false
		e.errorf("interface cannot contain these concrete types: %s", expected.KeysString())
	}
	if surplus.Len() > 0 {
		ok = false
		e.errorf("interface may additionally contain these concrete types: %s", surplus.KeysString())
	}
	return ok
	return false
}

func checkCallsExpectation(prog *ssa.Program, e *expectation, callgraph pointer.CallGraph) bool {
	// TODO(adonovan): this is inefficient and not robust against
	// typos.  Better to convert strings to *Functions during
	// expectation parsing (somehow).
	for caller, callees := range callgraph {
		if caller.Func().String() == e.args[0] {
			found := make(map[string]struct{})
			for callee := range callees {
				s := callee.Func().String()
				found[s] = struct{}{}
				if s == e.args[1] {
					return true // expectation satisfied
				}
			}
			e.errorf("found no call from %s to %s, but only to %s",
				e.args[0], e.args[1], join(found))
			return false
		}
	}
	e.errorf("didn't find any calls from %s", e.args[0])
	return false
}

func checkWarningExpectation(prog *ssa.Program, e *expectation, warnings []string) bool {
	// TODO(adonovan): check the position part of the warning too?
	re, err := regexp.Compile(e.args[0])
	if err != nil {
		e.errorf("invalid regular expression in @warning expectation: %s", err.Error())
		return false
	}

	if len(warnings) == 0 {
		e.errorf("@warning %s expectation, but no warnings", strconv.Quote(e.args[0]))
		return false
	}

	for _, warning := range warnings {
		if re.MatchString(warning) {
			return true
		}
	}

	e.errorf("@warning %s expectation not satised; found these warnings though:", strconv.Quote(e.args[0]))
	for _, warning := range warnings {
		fmt.Println("\t", warning)
	}
	return false
}

func TestInput(t *testing.T) {
	ok := true

	wd, err := os.Getwd()
	if err != nil {
		t.Errorf("os.Getwd: %s", err.Error())
		return
	}

	// 'go test' does a chdir so that relative paths in
	// diagnostics no longer make sense relative to the invoking
	// shell's cwd.  We print a special marker so that Emacs can
	// make sense of them.
	fmt.Fprintf(os.Stderr, "Entering directory `%s'\n", wd)

	for _, filename := range inputs {
		content, err := ioutil.ReadFile(filename)
		if err != nil {
			t.Errorf("couldn't read file '%s': %s", filename, err.Error())
			continue
		}

		if !doOneInput(string(content), filename) {
			ok = false
		}
	}
	if !ok {
		t.Fail()
	}
}

// join joins the elements of set with " | "s.
func join(set map[string]struct{}) string {
	var buf bytes.Buffer
	sep := ""
	for name := range set {
		buf.WriteString(sep)
		sep = " | "
		buf.WriteString(name)
	}
	return buf.String()
}

// split returns the list of sep-delimited non-empty strings in s.
func split(s, sep string) (r []string) {
	for _, elem := range strings.Split(s, sep) {
		elem = strings.TrimSpace(elem)
		if elem != "" {
			r = append(r, elem)
		}
	}
	return
}
