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

// This file contains tests for Eval.

package types_test

import (
	"go/ast"
	"go/importer"
	"go/parser"
	"go/token"
	"internal/testenv"
	"strings"
	"testing"

	. "go/types"
)

func testEval(t *testing.T, fset *token.FileSet, pkg *Package, pos token.Pos, expr string, typ Type, typStr, valStr string) {
	gotTv, err := Eval(fset, pkg, pos, expr)
	if err != nil {
		t.Errorf("Eval(%q) failed: %s", expr, err)
		return
	}
	if gotTv.Type == nil {
		t.Errorf("Eval(%q) got nil type but no error", expr)
		return
	}

	// compare types
	if typ != nil {
		// we have a type, check identity
		if !Identical(gotTv.Type, typ) {
			t.Errorf("Eval(%q) got type %s, want %s", expr, gotTv.Type, typ)
			return
		}
	} else {
		// we have a string, compare type string
		gotStr := gotTv.Type.String()
		if gotStr != typStr {
			t.Errorf("Eval(%q) got type %s, want %s", expr, gotStr, typStr)
			return
		}
	}

	// compare values
	gotStr := ""
	if gotTv.Value != nil {
		gotStr = gotTv.Value.ExactString()
	}
	if gotStr != valStr {
		t.Errorf("Eval(%q) got value %s, want %s", expr, gotStr, valStr)
	}
}

func TestEvalBasic(t *testing.T) {
	fset := token.NewFileSet()
	for _, typ := range Typ[Bool : String+1] {
		testEval(t, fset, nil, token.NoPos, typ.Name(), typ, "", "")
	}
}

func TestEvalComposite(t *testing.T) {
	fset := token.NewFileSet()
	for _, test := range independentTestTypes {
		testEval(t, fset, nil, token.NoPos, test.src, nil, test.str, "")
	}
}

func TestEvalArith(t *testing.T) {
	var tests = []string{
		`true`,
		`false == false`,
		`12345678 + 87654321 == 99999999`,
		`10 * 20 == 200`,
		`(1<<1000)*2 >> 100 == 2<<900`,
		`"foo" + "bar" == "foobar"`,
		`"abc" <= "bcd"`,
		`len([10]struct{}{}) == 2*5`,
	}
	fset := token.NewFileSet()
	for _, test := range tests {
		testEval(t, fset, nil, token.NoPos, test, Typ[UntypedBool], "", "true")
	}
}

func TestEvalPos(t *testing.T) {
	testenv.MustHaveGoBuild(t)

	// The contents of /*-style comments are of the form
	//	expr => value, type
	// where value may be the empty string.
	// Each expr is evaluated at the position of the comment
	// and the result is compared with the expected value
	// and type.
	var sources = []string{
		`
		package p
		import "fmt"
		import m "math"
		const c = 3.0
		type T []int
		func f(a int, s string) float64 {
			fmt.Println("calling f")
			_ = m.Pi // use package math
			const d int = c + 1
			var x int
			x = a + len(s)
			return float64(x)
			/* true => true, untyped bool */
			/* fmt.Println => , func(a ...interface{}) (n int, err error) */
			/* c => 3, untyped float */
			/* T => , p.T */
			/* a => , int */
			/* s => , string */
			/* d => 4, int */
			/* x => , int */
			/* d/c => 1, int */
			/* c/2 => 3/2, untyped float */
			/* m.Pi < m.E => false, untyped bool */
		}
		`,
		`
		package p
		/* c => 3, untyped float */
		type T1 /* T1 => , p.T1 */ struct {}
		var v1 /* v1 => , int */ = 42
		func /* f1 => , func(v1 float64) */ f1(v1 float64) {
			/* f1 => , func(v1 float64) */
			/* v1 => , float64 */
			var c /* c => 3, untyped float */ = "foo" /* c => , string */
			{
				var c struct {
					c /* c => , string */ int
				}
				/* c => , struct{c int} */
				_ = c
			}
			_ = func(a, b, c int) /* c => , string */ {
				/* c => , int */
			}
			_ = c
			type FT /* FT => , p.FT */ interface{}
		}
		`,
		`
		package p
		/* T => , p.T */
		`,
		`
		package p
		import "io"
		type R = io.Reader
		func _() {
			/* interface{R}.Read => , func(interface{io.Reader}, p []byte) (n int, err error) */
			_ = func() {
				/* interface{io.Writer}.Write => , func(interface{io.Writer}, p []byte) (n int, err error) */
				type io interface {} // must not shadow io in line above
			}
			type R interface {} // must not shadow R in first line of this function body
		}
		`,
	}

	fset := token.NewFileSet()
	var files []*ast.File
	for i, src := range sources {
		file, err := parser.ParseFile(fset, "p", src, parser.ParseComments)
		if err != nil {
			t.Fatalf("could not parse file %d: %s", i, err)
		}
		files = append(files, file)
	}

	conf := Config{Importer: importer.Default()}
	pkg, err := conf.Check("p", fset, files, nil)
	if err != nil {
		t.Fatal(err)
	}

	for _, file := range files {
		for _, group := range file.Comments {
			for _, comment := range group.List {
				s := comment.Text
				if len(s) >= 4 && s[:2] == "/*" && s[len(s)-2:] == "*/" {
					str, typ := split(s[2:len(s)-2], ", ")
					str, val := split(str, "=>")
					testEval(t, fset, pkg, comment.Pos(), str, nil, typ, val)
				}
			}
		}
	}
}

// split splits string s at the first occurrence of s.
func split(s, sep string) (string, string) {
	i := strings.Index(s, sep)
	return strings.TrimSpace(s[:i]), strings.TrimSpace(s[i+len(sep):])
}
