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

import (
	"flag"
	"fmt"
	"go/ast"
	"go/parser"
	"go/scanner"
	"go/token"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"code.google.com/p/go.exp/go/types"
)

var (
	// main operation modes
	pkgName   = flag.String("p", "", "process only those files in package pkgName")
	recursive = flag.Bool("r", false, "recursively process subdirectories")
	verbose   = flag.Bool("v", false, "verbose mode")
	allErrors = flag.Bool("e", false, "report all errors (not just the first 10 on different lines)")

	// debugging support
	parseComments = flag.Bool("comments", false, "parse comments (ignored if -ast not set)")
	printTrace    = flag.Bool("trace", false, "print parse trace")
	printAST      = flag.Bool("ast", false, "print AST")
)

var errorCount int

func usage() {
	fmt.Fprintf(os.Stderr, "usage: gotype [flags] [path ...]\n")
	flag.PrintDefaults()
	os.Exit(2)
}

func report(err error) {
	scanner.PrintError(os.Stderr, err)
	if list, ok := err.(scanner.ErrorList); ok {
		errorCount += len(list)
		return
	}
	errorCount++
}

// parse returns the AST for the Go source src.
// The filename is for error reporting only.
// The result is nil if there were errors or if
// the file does not belong to the -p package.
func parse(fset *token.FileSet, filename string, src []byte) *ast.File {
	if *verbose {
		fmt.Println(filename)
	}

	// ignore files with different package name
	if *pkgName != "" {
		file, err := parser.ParseFile(fset, filename, src, parser.PackageClauseOnly)
		if err != nil {
			report(err)
			return nil
		}
		if file.Name.Name != *pkgName {
			if *verbose {
				fmt.Printf("\tignored (package %s)\n", file.Name.Name)
			}
			return nil
		}
	}

	// parse entire file
	mode := parser.DeclarationErrors
	if *allErrors {
		mode |= parser.AllErrors
	}
	if *parseComments && *printAST {
		mode |= parser.ParseComments
	}
	if *printTrace {
		mode |= parser.Trace
	}
	file, err := parser.ParseFile(fset, filename, src, mode)
	if err != nil {
		report(err)
		return nil
	}
	if *printAST {
		ast.Print(fset, file)
	}

	return file
}

func parseStdin(fset *token.FileSet) (files []*ast.File) {
	src, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		report(err)
		return
	}
	const filename = "<standard input>"
	if file := parse(fset, filename, src); file != nil {
		files = []*ast.File{file}
	}
	return
}

func parseFiles(fset *token.FileSet, filenames []string) (files []*ast.File) {
	for _, filename := range filenames {
		src, err := ioutil.ReadFile(filename)
		if err != nil {
			report(err)
			continue
		}
		if file := parse(fset, filename, src); file != nil {
			files = append(files, file)
		}
	}
	return
}

func isGoFilename(filename string) bool {
	// ignore non-Go files
	return !strings.HasPrefix(filename, ".") && strings.HasSuffix(filename, ".go")
}

func processDirectory(dirname string) {
	f, err := os.Open(dirname)
	if err != nil {
		report(err)
		return
	}
	filenames, err := f.Readdirnames(-1)
	f.Close()
	if err != nil {
		report(err)
		// continue since filenames may not be empty
	}
	for i, filename := range filenames {
		filenames[i] = filepath.Join(dirname, filename)
	}
	processFiles(dirname, filenames, false)
}

func processFiles(path string, filenames []string, allFiles bool) {
	i := 0
	for _, filename := range filenames {
		switch info, err := os.Stat(filename); {
		case err != nil:
			report(err)
		case info.IsDir():
			if allFiles || *recursive {
				processDirectory(filename)
			}
		default:
			if allFiles || isGoFilename(info.Name()) {
				filenames[i] = filename
				i++
			}
		}
	}
	fset := token.NewFileSet()
	processPackage(path, fset, parseFiles(fset, filenames[0:i]))
}

func processPackage(path string, fset *token.FileSet, files []*ast.File) {
	type bailout struct{}
	ctxt := types.Context{
		Error: func(err error) {
			if !*allErrors && errorCount >= 10 {
				panic(bailout{})
			}
			report(err)
		},
	}

	defer func() {
		switch err := recover().(type) {
		case nil, bailout:
		default:
			panic(err)
		}
	}()

	ctxt.Check(path, fset, files...)
}

func main() {
	flag.Usage = usage
	flag.Parse()

	if flag.NArg() == 0 {
		fset := token.NewFileSet()
		processPackage("<stdin>", fset, parseStdin(fset))
	} else {
		processFiles("<files>", flag.Args(), true)
	}

	if errorCount > 0 {
		os.Exit(2)
	}
}
