// Copyright 2011 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 types2_test

import (
	"cmd/compile/internal/syntax"
	"fmt"
	"internal/testenv"
	"sort"
	"testing"

	. "cmd/compile/internal/types2"
)

type resolveTestImporter struct {
	importer ImporterFrom
	imported map[string]bool
}

func (imp *resolveTestImporter) Import(string) (*Package, error) {
	panic("should not be called")
}

func (imp *resolveTestImporter) ImportFrom(path, srcDir string, mode ImportMode) (*Package, error) {
	if mode != 0 {
		panic("mode must be 0")
	}
	if imp.importer == nil {
		imp.importer = defaultImporter().(ImporterFrom)
		imp.imported = make(map[string]bool)
	}
	pkg, err := imp.importer.ImportFrom(path, srcDir, mode)
	if err != nil {
		return nil, err
	}
	imp.imported[path] = true
	return pkg, nil
}

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

	sources := []string{
		`
		package p
		import "fmt"
		import "math"
		const pi = math.Pi
		func sin(x float64) float64 {
			return math.Sin(x)
		}
		var Println = fmt.Println
		`,
		`
		package p
		import "fmt"
		type errorStringer struct { fmt.Stringer; error }
		func f() string {
			_ = "foo"
			return fmt.Sprintf("%d", g())
		}
		func g() (x int) { return }
		`,
		`
		package p
		import . "go/parser"
		import "sync"
		func h() Mode { return ImportsOnly }
		var _, x int = 1, 2
		func init() {}
		type T struct{ *sync.Mutex; a, b, c int}
		type I interface{ m() }
		var _ = T{a: 1, b: 2, c: 3}
		func (_ T) m() {}
		func (T) _() {}
		var i I
		var _ = i.m
		func _(s []int) { for i, x := range s { _, _ = i, x } }
		func _(x interface{}) {
			switch x := x.(type) {
			case int:
				_ = x
			}
			switch {} // implicit 'true' tag
		}
		`,
		`
		package p
		type S struct{}
		func (T) _() {}
		func (T) _() {}
		`,
		`
		package p
		func _() {
		L0:
		L1:
			goto L0
			for {
				goto L1
			}
			if true {
				goto L2
			}
		L2:
		}
		`,
	}

	pkgnames := []string{
		"fmt",
		"math",
	}

	// parse package files
	var files []*syntax.File
	for i, src := range sources {
		f, err := parseSrc(fmt.Sprintf("sources[%d]", i), src)
		if err != nil {
			t.Fatal(err)
		}
		files = append(files, f)
	}

	// resolve and type-check package AST
	importer := new(resolveTestImporter)
	conf := Config{Importer: importer}
	uses := make(map[*syntax.Name]Object)
	defs := make(map[*syntax.Name]Object)
	_, err := conf.Check("testResolveIdents", files, &Info{Defs: defs, Uses: uses})
	if err != nil {
		t.Fatal(err)
	}

	// check that all packages were imported
	for _, name := range pkgnames {
		if !importer.imported[name] {
			t.Errorf("package %s not imported", name)
		}
	}

	// check that qualified identifiers are resolved
	for _, f := range files {
		syntax.Crawl(f, func(n syntax.Node) bool {
			if s, ok := n.(*syntax.SelectorExpr); ok {
				if x, ok := s.X.(*syntax.Name); ok {
					obj := uses[x]
					if obj == nil {
						t.Errorf("%s: unresolved qualified identifier %s", x.Pos(), x.Value)
						return true
					}
					if _, ok := obj.(*PkgName); ok && uses[s.Sel] == nil {
						t.Errorf("%s: unresolved selector %s", s.Sel.Pos(), s.Sel.Value)
						return true
					}
					return true
				}
				return true
			}
			return false
		})
	}

	for id, obj := range uses {
		if obj == nil {
			t.Errorf("%s: Uses[%s] == nil", id.Pos(), id.Value)
		}
	}

	// Check that each identifier in the source is found in uses or defs or both.
	// We need the foundUses/Defs maps (rather then just deleting the found objects
	// from the uses and defs maps) because syntax.Walk traverses shared nodes multiple
	// times (e.g. types in field lists such as "a, b, c int").
	foundUses := make(map[*syntax.Name]bool)
	foundDefs := make(map[*syntax.Name]bool)
	var both []string
	for _, f := range files {
		syntax.Crawl(f, func(n syntax.Node) bool {
			if x, ok := n.(*syntax.Name); ok {
				var objects int
				if _, found := uses[x]; found {
					objects |= 1
					foundUses[x] = true
				}
				if _, found := defs[x]; found {
					objects |= 2
					foundDefs[x] = true
				}
				switch objects {
				case 0:
					t.Errorf("%s: unresolved identifier %s", x.Pos(), x.Value)
				case 3:
					both = append(both, x.Value)
				}
				return true
			}
			return false
		})
	}

	// check the expected set of idents that are simultaneously uses and defs
	sort.Strings(both)
	if got, want := fmt.Sprint(both), "[Mutex Stringer error]"; got != want {
		t.Errorf("simultaneous uses/defs = %s, want %s", got, want)
	}

	// any left-over identifiers didn't exist in the source
	for x := range uses {
		if !foundUses[x] {
			t.Errorf("%s: identifier %s not present in source", x.Pos(), x.Value)
		}
	}
	for x := range defs {
		if !foundDefs[x] {
			t.Errorf("%s: identifier %s not present in source", x.Pos(), x.Value)
		}
	}

	// TODO(gri) add tests to check ImplicitObj callbacks
}
