// 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
//
// A trailing slash in a pattern is ignored.  (Path components of Go
// package names are separated by slash, not the platform's path separator.)
//
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(strings.TrimSuffix(arg, "/"), neg)
		}
	}

	return pkgs
}
