// 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() {
		wg.Go(func() {
			allPackages(ctxt, root, ch)
		})
	}
	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 {
			if fi.IsDir() {
				wg.Go(func() {
					walkDir(filepath.Join(dir, fi.Name()))
				})
			}
		}
	}

	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, ok := strings.CutSuffix(arg, "/..."); ok {
			// 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
}
