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

import (
	"fmt"
	"go/ast"
	"go/parser"
	"testing"

	_ "llvm.org/llgo/third_party/go.tools/go/gcimporter"
	. "llvm.org/llgo/third_party/go.tools/go/types"
)

var builtinCalls = []struct {
	name, src, sig string
}{
	{"append", `var s []int; _ = append(s)`, `func([]int, ...int) []int`},
	{"append", `var s []int; _ = append(s, 0)`, `func([]int, ...int) []int`},
	{"append", `var s []int; _ = (append)(s, 0)`, `func([]int, ...int) []int`},
	{"append", `var s []byte; _ = ((append))(s, 0)`, `func([]byte, ...byte) []byte`},
	{"append", `var s []byte; _ = append(s, "foo"...)`, `func([]byte, string...) []byte`},
	{"append", `type T []byte; var s T; var str string; _ = append(s, str...)`, `func(p.T, string...) p.T`},
	{"append", `type T []byte; type U string; var s T; var str U; _ = append(s, str...)`, `func(p.T, p.U...) p.T`},

	{"cap", `var s [10]int; _ = cap(s)`, `invalid type`},  // constant
	{"cap", `var s [10]int; _ = cap(&s)`, `invalid type`}, // constant
	{"cap", `var s []int64; _ = cap(s)`, `func([]int64) int`},
	{"cap", `var c chan<-bool; _ = cap(c)`, `func(chan<- bool) int`},

	{"len", `_ = len("foo")`, `invalid type`}, // constant
	{"len", `var s string; _ = len(s)`, `func(string) int`},
	{"len", `var s [10]int; _ = len(s)`, `invalid type`},  // constant
	{"len", `var s [10]int; _ = len(&s)`, `invalid type`}, // constant
	{"len", `var s []int64; _ = len(s)`, `func([]int64) int`},
	{"len", `var c chan<-bool; _ = len(c)`, `func(chan<- bool) int`},
	{"len", `var m map[string]float32; _ = len(m)`, `func(map[string]float32) int`},

	{"close", `var c chan int; close(c)`, `func(chan int)`},
	{"close", `var c chan<- chan string; close(c)`, `func(chan<- chan string)`},

	{"complex", `_ = complex(1, 0)`, `invalid type`}, // constant
	{"complex", `var re float32; _ = complex(re, 1.0)`, `func(float32, float32) complex64`},
	{"complex", `var im float64; _ = complex(1, im)`, `func(float64, float64) complex128`},
	{"complex", `type F32 float32; var re, im F32; _ = complex(re, im)`, `func(p.F32, p.F32) complex64`},
	{"complex", `type F64 float64; var re, im F64; _ = complex(re, im)`, `func(p.F64, p.F64) complex128`},

	{"copy", `var src, dst []byte; copy(dst, src)`, `func([]byte, []byte) int`},
	{"copy", `type T [][]int; var src, dst T; _ = copy(dst, src)`, `func(p.T, p.T) int`},
	{"copy", `var src string; var dst []byte; copy(dst, src)`, `func([]byte, string) int`},
	{"copy", `type T string; type U []byte; var src T; var dst U; copy(dst, src)`, `func(p.U, p.T) int`},
	{"copy", `var dst []byte; copy(dst, "hello")`, `func([]byte, string) int`},

	{"delete", `var m map[string]bool; delete(m, "foo")`, `func(map[string]bool, string)`},
	{"delete", `type (K string; V int); var m map[K]V; delete(m, "foo")`, `func(map[p.K]p.V, p.K)`},

	{"imag", `_ = imag(1i)`, `invalid type`}, // constant
	{"imag", `var c complex64; _ = imag(c)`, `func(complex64) float32`},
	{"imag", `var c complex128; _ = imag(c)`, `func(complex128) float64`},
	{"imag", `type C64 complex64; var c C64; _ = imag(c)`, `func(p.C64) float32`},
	{"imag", `type C128 complex128; var c C128; _ = imag(c)`, `func(p.C128) float64`},

	{"real", `_ = real(1i)`, `invalid type`}, // constant
	{"real", `var c complex64; _ = real(c)`, `func(complex64) float32`},
	{"real", `var c complex128; _ = real(c)`, `func(complex128) float64`},
	{"real", `type C64 complex64; var c C64; _ = real(c)`, `func(p.C64) float32`},
	{"real", `type C128 complex128; var c C128; _ = real(c)`, `func(p.C128) float64`},

	{"make", `_ = make([]int, 10)`, `func([]int, int) []int`},
	{"make", `type T []byte; _ = make(T, 10, 20)`, `func(p.T, int, int) p.T`},

	{"new", `_ = new(int)`, `func(int) *int`},
	{"new", `type T struct{}; _ = new(T)`, `func(p.T) *p.T`},

	{"panic", `panic(0)`, `func(interface{})`},
	{"panic", `panic("foo")`, `func(interface{})`},

	{"print", `print()`, `func()`},
	{"print", `print(0)`, `func(int)`},
	{"print", `print(1, 2.0, "foo", true)`, `func(int, float64, string, bool)`},

	{"println", `println()`, `func()`},
	{"println", `println(0)`, `func(int)`},
	{"println", `println(1, 2.0, "foo", true)`, `func(int, float64, string, bool)`},

	{"recover", `recover()`, `func() interface{}`},
	{"recover", `_ = recover()`, `func() interface{}`},

	{"Alignof", `_ = unsafe.Alignof(0)`, `invalid type`},                 // constant
	{"Alignof", `var x struct{}; _ = unsafe.Alignof(x)`, `invalid type`}, // constant

	{"Offsetof", `var x struct{f bool}; _ = unsafe.Offsetof(x.f)`, `invalid type`},           // constant
	{"Offsetof", `var x struct{_ int; f bool}; _ = unsafe.Offsetof((&x).f)`, `invalid type`}, // constant

	{"Sizeof", `_ = unsafe.Sizeof(0)`, `invalid type`},                 // constant
	{"Sizeof", `var x struct{}; _ = unsafe.Sizeof(x)`, `invalid type`}, // constant

	{"assert", `assert(true)`, `invalid type`},                                    // constant
	{"assert", `type B bool; const pred B = 1 < 2; assert(pred)`, `invalid type`}, // constant

	// no tests for trace since it produces output as a side-effect
}

func TestBuiltinSignatures(t *testing.T) {
	DefPredeclaredTestFuncs()

	seen := map[string]bool{"trace": true} // no test for trace built-in; add it manually
	for _, call := range builtinCalls {
		testBuiltinSignature(t, call.name, call.src, call.sig)
		seen[call.name] = true
	}

	// make sure we didn't miss one
	for _, name := range Universe.Names() {
		if _, ok := Universe.Lookup(name).(*Builtin); ok && !seen[name] {
			t.Errorf("missing test for %s", name)
		}
	}
	for _, name := range Unsafe.Scope().Names() {
		if _, ok := Unsafe.Scope().Lookup(name).(*Builtin); ok && !seen[name] {
			t.Errorf("missing test for unsafe.%s", name)
		}
	}
}

func testBuiltinSignature(t *testing.T, name, src0, want string) {
	src := fmt.Sprintf(`package p; import "unsafe"; type _ unsafe.Pointer /* use unsafe */; func _() { %s }`, src0)
	f, err := parser.ParseFile(fset, "", src, 0)
	if err != nil {
		t.Errorf("%s: %s", src0, err)
		return
	}

	var conf Config
	uses := make(map[*ast.Ident]Object)
	types := make(map[ast.Expr]TypeAndValue)
	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Uses: uses, Types: types})
	if err != nil {
		t.Errorf("%s: %s", src0, err)
		return
	}

	// find called function
	n := 0
	var fun ast.Expr
	for x := range types {
		if call, _ := x.(*ast.CallExpr); call != nil {
			fun = call.Fun
			n++
		}
	}
	if n != 1 {
		t.Errorf("%s: got %d CallExprs; want 1", src0, n)
		return
	}

	// check recorded types for fun and descendents (may be parenthesized)
	for {
		// the recorded type for the built-in must match the wanted signature
		typ := types[fun].Type
		if typ == nil {
			t.Errorf("%s: no type recorded for %s", src0, ExprString(fun))
			return
		}
		if got := typ.String(); got != want {
			t.Errorf("%s: got type %s; want %s", src0, got, want)
			return
		}

		// called function must be a (possibly parenthesized, qualified)
		// identifier denoting the expected built-in
		switch p := fun.(type) {
		case *ast.Ident:
			obj := uses[p]
			if obj == nil {
				t.Errorf("%s: no object found for %s", src0, p)
				return
			}
			bin, _ := obj.(*Builtin)
			if bin == nil {
				t.Errorf("%s: %s does not denote a built-in", src0, p)
				return
			}
			if bin.Name() != name {
				t.Errorf("%s: got built-in %s; want %s", src0, bin.Name(), name)
				return
			}
			return // we're done

		case *ast.ParenExpr:
			fun = p.X // unpack

		case *ast.SelectorExpr:
			// built-in from package unsafe - ignore details
			return // we're done

		default:
			t.Errorf("%s: invalid function call", src0)
			return
		}
	}
}
