// Copyright 2014 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 buildutil provides utilities related to the go/build
// package in the standard library.
//
// All I/O is done via the build.Context file system interface, which must
// be concurrency-safe.
package buildutil // import "golang.org/x/tools/go/buildutil"

import (
	"go/build"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"sync"
)

// AllPackages returns the package path of each Go package in any source
// directory of the specified build context (e.g. $GOROOT or an element
// of $GOPATH).  Errors are ignored.  The results are sorted.
// All package paths are canonical, and thus may contain "/vendor/".
//
// The result may include import paths for directories that contain no
// *.go files, such as "archive" (in $GOROOT/src).
//
// All I/O is done via the build.Context file system interface,
// which must be concurrency-safe.
//
func AllPackages(ctxt *build.Context) []string {
	var list []string
	ForEachPackage(ctxt, func(pkg string, _ error) {
		list = append(list, pkg)
	})
	sort.Strings(list)
	return list
}

// ForEachPackage calls the found function with the package path of
// each Go package it finds in any source directory of the specified
// build context (e.g. $GOROOT or an element of $GOPATH).
// All package paths are canonical, and thus may contain "/vendor/".
//
// If the package directory exists but could not be read, the second
// argument to the found function provides the error.
//
// All I/O is done via the build.Context file system interface,
// which must be concurrency-safe.
//
func ForEachPackage(ctxt *build.Context, found func(importPath string, err error)) {
	ch := make(chan item)

	var wg sync.WaitGroup
	for _, root := range ctxt.SrcDirs() {
		root := root
		wg.Add(1)
		go func() {
			allPackages(ctxt, root, ch)
			wg.Done()
		}()
	}
	go func() {
		wg.Wait()
		close(ch)
	}()

	// All calls to found occur in the caller's goroutine.
	for i := range ch {
		found(i.importPath, i.err)
	}
}

type item struct {
	importPath string
	err        error // (optional)
}

// We use a process-wide counting semaphore to limit
// the number of parallel calls to ReadDir.
var ioLimit = make(chan bool, 20)

func allPackages(ctxt *build.Context, root string, ch chan<- item) {
	root = filepath.Clean(root) + string(os.PathSeparator)

	var wg sync.WaitGroup

	var walkDir func(dir string)
	walkDir = func(dir string) {
		// Avoid .foo, _foo, and testdata directory trees.
		base := filepath.Base(dir)
		if base == "" || base[0] == '.' || base[0] == '_' || base == "testdata" {
			return
		}

		pkg := filepath.ToSlash(strings.TrimPrefix(dir, root))

		// Prune search if we encounter any of these import paths.
		switch pkg {
		case "builtin":
			return
		}

		ioLimit <- true
		files, err := ReadDir(ctxt, dir)
		<-ioLimit
		if pkg != "" || err != nil {
			ch <- item{pkg, err}
		}
		for _, fi := range files {
			fi := fi
			if fi.IsDir() {
				wg.Add(1)
				go func() {
					walkDir(filepath.Join(dir, fi.Name()))
					wg.Done()
				}()
			}
		}
	}

	walkDir(root)
	wg.Wait()
}

// ExpandPatterns returns the set of packages matched by patterns,
// which may have the following forms:
//
//		golang.org/x/tools/cmd/guru     # a single package
//		golang.org/x/tools/...          # all packages beneath dir
//		...                             # the entire workspace.
//
// Order is significant: a pattern preceded by '-' removes matching
// packages from the set.  For example, these patterns match all encoding
// packages except encoding/xml:
//
// 	encoding/... -encoding/xml
//
func ExpandPatterns(ctxt *build.Context, patterns []string) map[string]bool {
	// TODO(adonovan): support other features of 'go list':
	// - "std"/"cmd"/"all" meta-packages
	// - "..." not at the end of a pattern
	// - relative patterns using "./" or "../" prefix

	pkgs := make(map[string]bool)
	doPkg := func(pkg string, neg bool) {
		if neg {
			delete(pkgs, pkg)
		} else {
			pkgs[pkg] = true
		}
	}

	// Scan entire workspace if wildcards are present.
	// TODO(adonovan): opt: scan only the necessary subtrees of the workspace.
	var all []string
	for _, arg := range patterns {
		if strings.HasSuffix(arg, "...") {
			all = AllPackages(ctxt)
			break
		}
	}

	for _, arg := range patterns {
		if arg == "" {
			continue
		}

		neg := arg[0] == '-'
		if neg {
			arg = arg[1:]
		}

		if arg == "..." {
			// ... matches all packages
			for _, pkg := range all {
				doPkg(pkg, neg)
			}
		} else if dir := strings.TrimSuffix(arg, "/..."); dir != arg {
			// dir/... matches all packages beneath dir
			for _, pkg := range all {
				if strings.HasPrefix(pkg, dir) &&
					(len(pkg) == len(dir) || pkg[len(dir)] == '/') {
					doPkg(pkg, neg)
				}
			}
		} else {
			// single package
			doPkg(arg, neg)
		}
	}

	return pkgs
}
