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

// This file defines various utility functions exposed by the package
// and used by it.

import (
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"os"
	"path/filepath"
	"strconv"
	"sync"
)

var cwd string

func init() {
	var err error
	cwd, err = os.Getwd()
	if err != nil {
		panic("getcwd failed: " + err.Error())
	}
}

// parsePackageFiles enumerates the files belonging to package path,
// then loads, parses and returns them.
//
// 'which' is a list of flags indicating which files to include:
//    'g': include non-test *.go source files (GoFiles)
//    't': include in-package *_test.go source files (TestGoFiles)
//    'x': include external *_test.go source files. (XTestGoFiles)
//
func parsePackageFiles(ctxt *build.Context, fset *token.FileSet, path string, which string) ([]*ast.File, error) {
	// Set the "!cgo" go/build tag, preferring (dummy) Go to
	// native C implementations of net.cgoLookupHost et al.
	ctxt2 := *ctxt
	ctxt2.CgoEnabled = false

	// TODO(adonovan): fix: Do we need cwd? Shouldn't
	// ImportDir(path) / $GOROOT suffice?
	bp, err := ctxt2.Import(path, cwd, 0)
	if _, ok := err.(*build.NoGoError); ok {
		return nil, nil // empty directory
	}
	if err != nil {
		return nil, err // import failed
	}

	var filenames []string
	for _, c := range which {
		var s []string
		switch c {
		case 'g':
			s = bp.GoFiles
		case 't':
			s = bp.TestGoFiles
		case 'x':
			s = bp.XTestGoFiles
		default:
			panic(c)
		}
		filenames = append(filenames, s...)
	}
	return ParseFiles(fset, bp.Dir, filenames...)
}

// ParseFiles parses the Go source files files within directory dir
// and returns their ASTs, or the first parse error if any.
//
func ParseFiles(fset *token.FileSet, dir string, files ...string) ([]*ast.File, error) {
	var wg sync.WaitGroup
	n := len(files)
	parsed := make([]*ast.File, n, n)
	errors := make([]error, n, n)
	for i, file := range files {
		if !filepath.IsAbs(file) {
			file = filepath.Join(dir, file)
		}
		wg.Add(1)
		go func(i int, file string) {
			parsed[i], errors[i] = parser.ParseFile(fset, file, nil, parser.DeclarationErrors)
			wg.Done()
		}(i, file)
	}
	wg.Wait()

	for _, err := range errors {
		if err != nil {
			return nil, err
		}
	}
	return parsed, nil
}

// ---------- Internal helpers ----------

// unparen returns e with any enclosing parentheses stripped.
func unparen(e ast.Expr) ast.Expr {
	for {
		p, ok := e.(*ast.ParenExpr)
		if !ok {
			break
		}
		e = p.X
	}
	return e
}

func unreachable() {
	panic("unreachable")
}

// importsOf returns the set of paths imported by the specified files.
func importsOf(p string, files []*ast.File) map[string]bool {
	imports := make(map[string]bool)
outer:
	for _, file := range files {
		for _, decl := range file.Decls {
			if decl, ok := decl.(*ast.GenDecl); ok {
				if decl.Tok != token.IMPORT {
					break outer // stop at the first non-import
				}
				for _, spec := range decl.Specs {
					spec := spec.(*ast.ImportSpec)
					if path, _ := strconv.Unquote(spec.Path.Value); path != "C" {
						imports[path] = true
					}
				}
			} else {
				break outer // stop at the first non-import
			}
		}
	}
	return imports
}
