// 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 tests types.Check by using it to
// typecheck the standard library and tests.

package types

import (
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/scanner"
	"go/token"
	"io/ioutil"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"
)

var verbose = flag.Bool("types.v", false, "verbose mode")

var (
	pkgCount int // number of packages processed
	start    = time.Now()
)

func TestStdlib(t *testing.T) {
	walkDirs(t, filepath.Join(runtime.GOROOT(), "src/pkg"))
	if *verbose {
		fmt.Println(pkgCount, "packages typechecked in", time.Since(start))
	}
}

func testTestDir(t *testing.T, path string, ignore ...string) {
	files, err := ioutil.ReadDir(path)
	if err != nil {
		t.Fatal(err)
	}

	excluded := make(map[string]bool)
	for _, filename := range ignore {
		excluded[filename] = true
	}

	fset := token.NewFileSet()
	for _, f := range files {
		// filter directory contents
		if f.IsDir() || !strings.HasSuffix(f.Name(), ".go") || excluded[f.Name()] {
			continue
		}

		// parse file
		filename := filepath.Join(path, f.Name())
		// TODO(gri) The parser loses comments when bailing out early,
		//           and then we don't see the errorcheck command for
		//           some files. Use parser.AllErrors for now. Fix this.
		file, err := parser.ParseFile(fset, filename, nil, parser.ParseComments|parser.AllErrors)

		// check per-file instructions
		// For now we only check some cases.
		expectErrors := false
		if len(file.Comments) > 0 {
			if group := file.Comments[0]; len(group.List) > 0 {
				cmd := strings.TrimSpace(group.List[0].Text[2:]) // 2: ignore // or /* of comment
				switch cmd {
				case "skip", "compiledir":
					continue
				case "errorcheck":
					expectErrors = true
				}
			}
		}

		// type-check file if it parsed cleanly
		if err == nil {
			_, err = Check(filename, fset, []*ast.File{file})
		}

		if expectErrors {
			if err == nil {
				t.Errorf("expected errors but found none in %s", filename)
			}
		} else {
			if err != nil {
				t.Error(err)
			}
		}
	}
}

func TestStdtest(t *testing.T) {
	testTestDir(t, filepath.Join(runtime.GOROOT(), "test"),
		"cmplxdivide.go",       // also needs file cmplxdivide1.go - ignore
		"goto.go", "label1.go", // TODO(gri) implement missing label checks
		"mapnan.go", "sigchld.go", // don't work on Windows; testTestDir should consult build tags
		"sizeof.go", "switch.go", // TODO(gri) tone down duplicate checking in expr switches
		"typeswitch2.go", // TODO(gri) implement duplicate checking in type switches
	)
}

func TestStdfixed(t *testing.T) {
	testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "fixedbugs"),
		"bug050.go", "bug088.go", "bug106.go", // TODO(gri) parser loses comments when bailing out early
		"bug222.go", "bug282.go", "bug306.go", // TODO(gri) parser loses comments when bailing out early
		"issue4776.go",                        // TODO(gri) parser loses comments when bailing out early
		"bug136.go", "bug179.go", "bug344.go", // TODO(gri) implement missing label checks
		"bug251.go",                           // TODO(gri) incorrect cycle checks for interface types
		"bug165.go",                           // TODO(gri) isComparable not working for incomplete struct type
		"bug176.go",                           // TODO(gri) composite literal array index must be non-negative constant
		"bug200.go",                           // TODO(gri) complete duplicate checking in expr switches
		"bug223.go", "bug413.go", "bug459.go", // TODO(gri) complete initialization checks
		"bug248.go", "bug302.go", "bug369.go", // complex test instructions - ignore
		"bug250.go",    // TODO(gri) fix recursive interfaces
		"bug326.go",    // TODO(gri) assignment doesn't guard against len(rhs) == 0
		"bug373.go",    // TODO(gri) implement use checks
		"bug376.go",    // TODO(gri) built-ins must be called (no built-in function expressions)
		"issue3924.go", // TODO(gri) && and || produce bool result (not untyped bool)
		"issue4847.go", // TODO(gri) initialization cycle error not found
	)
}

func TestStdken(t *testing.T) {
	testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "ken"))
}

// Package paths of excluded packages.
var excluded = map[string]bool{
	"builtin": true,
}

// typecheck typechecks the given package files.
func typecheck(t *testing.T, path string, filenames []string) {
	fset := token.NewFileSet()

	// parse package files
	var files []*ast.File
	for _, filename := range filenames {
		file, err := parser.ParseFile(fset, filename, nil, parser.AllErrors)
		if err != nil {
			// the parser error may be a list of individual errors; report them all
			if list, ok := err.(scanner.ErrorList); ok {
				for _, err := range list {
					t.Error(err)
				}
				return
			}
			t.Error(err)
			return
		}

		if *verbose {
			if len(files) == 0 {
				fmt.Println("package", file.Name.Name)
			}
			fmt.Println("\t", filename)
		}

		files = append(files, file)
	}

	// typecheck package files
	var conf Config
	conf.Error = func(err error) { t.Error(err) }
	conf.Check(path, fset, files, nil)
	pkgCount++
}

// pkgfiles returns the list of package files for the given directory.
func pkgfiles(t *testing.T, dir string) []string {
	ctxt := build.Default
	ctxt.CgoEnabled = false
	pkg, err := ctxt.ImportDir(dir, 0)
	if err != nil {
		if _, nogo := err.(*build.NoGoError); !nogo {
			t.Error(err)
		}
		return nil
	}
	if excluded[pkg.ImportPath] {
		return nil
	}
	var filenames []string
	for _, name := range pkg.GoFiles {
		filenames = append(filenames, filepath.Join(pkg.Dir, name))
	}
	for _, name := range pkg.TestGoFiles {
		filenames = append(filenames, filepath.Join(pkg.Dir, name))
	}
	return filenames
}

// Note: Could use filepath.Walk instead of walkDirs but that wouldn't
//       necessarily be shorter or clearer after adding the code to
//       terminate early for -short tests.

func walkDirs(t *testing.T, dir string) {
	// limit run time for short tests
	if testing.Short() && time.Since(start) >= 750*time.Millisecond {
		return
	}

	fis, err := ioutil.ReadDir(dir)
	if err != nil {
		t.Error(err)
		return
	}

	// typecheck package in directory
	if files := pkgfiles(t, dir); files != nil {
		typecheck(t, dir, files)
	}

	// traverse subdirectories, but don't walk into testdata
	for _, fi := range fis {
		if fi.IsDir() && fi.Name() != "testdata" {
			walkDirs(t, filepath.Join(dir, fi.Name()))
		}
	}
}
