package dependency

import (
	"container/list"
	"errors"
	"runtime"
	"sort"
	//"go/build"
	"os"
	"path/filepath"
	"strings"

	"github.com/Masterminds/glide/cfg"
	"github.com/Masterminds/glide/msg"
	gpath "github.com/Masterminds/glide/path"
	"github.com/Masterminds/glide/util"
)

// MissingPackageHandler handles the case where a package is missing during scanning.
//
// It returns true if the package can be passed to the resolver, false otherwise.
// False may be returned even if error is nil.
type MissingPackageHandler interface {
	// NotFound is called when the Resolver fails to find a package with the given name.
	//
	// NotFound returns true when the resolver should attempt to re-resole the
	// dependency (e.g. when NotFound has gone and fetched the missing package).
	//
	// When NotFound returns false, the Resolver does not try to do any additional
	// work on the missing package.
	//
	// NotFound only returns errors when it fails to perform its internal goals.
	// When it returns false with no error, this indicates that the handler did
	// its job, but the resolver should not do any additional work on the
	// package.
	NotFound(pkg string, addTest bool) (bool, error)

	// OnGopath is called when the Resolver finds a dependency, but it's only on GOPATH.
	//
	// OnGopath provides an opportunity to copy, move, warn, or ignore cases like this.
	//
	// OnGopath returns true when the resolver should attempt to re-resolve the
	// dependency (e.g. when the dependency is copied to a new location).
	//
	// When OnGopath returns false, the Resolver does not try to do any additional
	// work on the package.
	//
	// An error indicates that OnGopath cannot complete its intended operation.
	// Not all false results are errors.
	OnGopath(pkg string, addTest bool) (bool, error)

	// InVendor is called when the Resolver finds a dependency in the vendor/ directory.
	//
	// This can be used update a project found in the vendor/ folder.
	InVendor(pkg string, addTest bool) error

	// PkgPath is called to find the location locally to scan. This gives the
	// handler to do things such as use a cached location.
	PkgPath(pkg string) string
}

// DefaultMissingPackageHandler is the default handler for missing packages.
//
// When asked to handle a missing package, it will report the miss as a warning,
// and then store the package in the Missing slice for later access.
type DefaultMissingPackageHandler struct {
	Missing []string
	Gopath  []string
	Prefix  string
}

// NotFound prints a warning and then stores the package name in Missing.
//
// It never returns an error, and it always returns false.
func (d *DefaultMissingPackageHandler) NotFound(pkg string, addTest bool) (bool, error) {
	msg.Warn("Package %s is not installed", pkg)
	d.Missing = append(d.Missing, pkg)
	return false, nil
}

// OnGopath is run when a package is missing from vendor/ but found in the GOPATH
func (d *DefaultMissingPackageHandler) OnGopath(pkg string, addTest bool) (bool, error) {
	msg.Warn("Package %s is only on GOPATH.", pkg)
	d.Gopath = append(d.Gopath, pkg)
	return false, nil
}

// InVendor is run when a package is found in the vendor/ folder
func (d *DefaultMissingPackageHandler) InVendor(pkg string, addTest bool) error {
	msg.Info("Package %s found in vendor/ folder", pkg)
	return nil
}

// PkgPath returns the path to the package
func (d *DefaultMissingPackageHandler) PkgPath(pkg string) string {
	if d.Prefix != "" {
		return filepath.Join(d.Prefix, pkg)
	}
	return pkg
}

// VersionHandler sets the version for a package when found while scanning.
//
// When a package if found it needs to be on the correct version before
// scanning its contents to be sure to pick up the right elements for that
// version.
type VersionHandler interface {

	// Process provides an opportunity to process the codebase for version setting.
	Process(pkg string) error

	// SetVersion sets the version for a package. An error is returned if there
	// was a problem setting the version.
	SetVersion(pkg string, testDep bool) error
}

// DefaultVersionHandler is the default handler for setting the version.
//
// The default handler leaves the current version and skips setting a version.
// For a handler that alters the version see the handler included in the repo
// package as part of the installer.
type DefaultVersionHandler struct{}

// Process a package to aide in version setting.
func (d *DefaultVersionHandler) Process(pkg string) error {
	return nil
}

// SetVersion here sends a message when a package is found noting that it
// did not set the version.
func (d *DefaultVersionHandler) SetVersion(pkg string, testDep bool) error {
	msg.Warn("Version not set for package %s", pkg)
	return nil
}

// Resolver resolves a dependency tree.
//
// It operates in two modes:
// - local resolution (ResolveLocal) determines the dependencies of the local project.
// - vendor resolving (Resolve, ResolveAll) determines the dependencies of vendored
//   projects.
//
// Local resolution is for guessing initial dependencies. Vendor resolution is
// for determining vendored dependencies.
type Resolver struct {
	Handler        MissingPackageHandler
	VersionHandler VersionHandler
	VendorDir      string
	BuildContext   *util.BuildCtxt
	Config         *cfg.Config

	// ResolveAllFiles toggles deep scanning.
	// If this is true, resolve by scanning all files, not by walking the
	// import tree.
	ResolveAllFiles bool

	// ResolveTest sets if test dependencies should be resolved.
	ResolveTest bool

	// Items already in the queue.
	alreadyQ map[string]bool

	// Attempts to scan that had unrecoverable error.
	hadError map[string]bool

	basedir string
	seen    map[string]bool

	// findCache caches hits from Find. This reduces the number of filesystem
	// touches that have to be done for dependency resolution.
	findCache map[string]*PkgInfo
}

// NewResolver returns a new Resolver initialized with the DefaultMissingPackageHandler.
//
// This will return an error if the given path does not meet the basic criteria
// for a Go source project. For example, basedir must have a vendor subdirectory.
//
// The BuildContext uses the "go/build".Default to resolve dependencies.
func NewResolver(basedir string) (*Resolver, error) {

	var err error
	basedir, err = filepath.Abs(basedir)
	if err != nil {
		return nil, err
	}

	basedir, err = checkForBasedirSymlink(basedir)

	if err != nil {
		return nil, err
	}

	vdir := filepath.Join(basedir, "vendor")

	buildContext, err := util.GetBuildContext()
	if err != nil {
		return nil, err
	}

	r := &Resolver{
		Handler:        &DefaultMissingPackageHandler{Missing: []string{}, Gopath: []string{}},
		VersionHandler: &DefaultVersionHandler{},
		basedir:        basedir,
		VendorDir:      vdir,
		BuildContext:   buildContext,
		seen:           map[string]bool{},
		alreadyQ:       map[string]bool{},
		hadError:       map[string]bool{},
		findCache:      map[string]*PkgInfo{},

		// The config instance here should really be replaced with a real one.
		Config: &cfg.Config{},
	}

	// TODO: Make sure the build context is correctly set up. Especially in
	// regards to GOROOT, which is not always set.

	return r, nil
}

// Resolve takes a package name and returns all of the imported package names.
//
// If a package is not found, this calls the Fetcher. If the Fetcher returns
// true, it will re-try traversing that package for dependencies. Otherwise it
// will add that package to the deps array and continue on without trying it.
// And if the Fetcher returns an error, this will stop resolution and return
// the error.
//
// If basepath is set to $GOPATH, this will start from that package's root there.
// If basepath is set to a project's vendor path, the scanning will begin from
// there.
func (r *Resolver) Resolve(pkg, basepath string) ([]string, error) {
	target := filepath.Join(basepath, filepath.FromSlash(pkg))
	//msg.Debug("Scanning %s", target)
	l := list.New()
	l.PushBack(target)

	// In this mode, walk the entire tree.
	if r.ResolveAllFiles {
		return r.resolveList(l, false, false)
	}
	return r.resolveImports(l, false, false)
}

// dirHasPrefix tests whether the directory dir begins with prefix.
func dirHasPrefix(dir, prefix string) bool {
	if runtime.GOOS != "windows" {
		return strings.HasPrefix(dir, prefix)
	}
	return len(dir) >= len(prefix) && strings.EqualFold(dir[:len(prefix)], prefix)
}

// ResolveLocal resolves dependencies for the current project.
//
// This begins with the project, builds up a list of external dependencies.
//
// If the deep flag is set to true, this will then resolve all of the dependencies
// of the dependencies it has found. If not, it will return just the packages that
// the base project relies upon.
func (r *Resolver) ResolveLocal(deep bool) ([]string, []string, error) {
	// We build a list of local source to walk, then send this list
	// to resolveList.
	msg.Debug("Resolving local dependencies")
	l := list.New()
	tl := list.New()
	alreadySeen := map[string]bool{}
	talreadySeen := map[string]bool{}
	err := filepath.Walk(r.basedir, func(path string, fi os.FileInfo, err error) error {
		if err != nil && err != filepath.SkipDir {
			return err
		}
		pt := strings.TrimPrefix(path, r.basedir+string(os.PathSeparator))
		pt = strings.TrimSuffix(pt, string(os.PathSeparator))
		if r.Config.HasExclude(pt) {
			msg.Debug("Excluding %s", pt)
			return filepath.SkipDir
		}
		if !fi.IsDir() {
			return nil
		}
		if !srcDir(fi) {
			return filepath.SkipDir
		}

		// Scan for dependencies, and anything that's not part of the local
		// package gets added to the scan list.
		var imps []string
		var testImps []string
		p, err := r.BuildContext.ImportDir(path, 0)
		if err != nil {
			if strings.HasPrefix(err.Error(), "no buildable Go source") {
				return nil
			} else if strings.HasPrefix(err.Error(), "found packages ") {
				// If we got here it's because a package and multiple packages
				// declared. This is often because of an example with a package
				// or main but +build ignore as a build tag. In that case we
				// try to brute force the packages with a slower scan.
				imps, testImps, err = IterativeScan(path)
				if err != nil {
					return err
				}
			} else {
				return err
			}
		} else {
			imps = p.Imports
			testImps = dedupeStrings(p.TestImports, p.XTestImports)
		}

		// We are only looking for dependencies in vendor. No root, cgo, etc.
		for _, imp := range imps {
			if r.Config.HasIgnore(imp) {
				continue
			}
			if alreadySeen[imp] {
				continue
			}
			alreadySeen[imp] = true
			info := r.FindPkg(imp)
			switch info.Loc {
			case LocUnknown, LocVendor:
				l.PushBack(filepath.Join(r.VendorDir, filepath.FromSlash(imp))) // Do we need a path on this?
			case LocGopath:
				if !dirHasPrefix(info.Path, r.basedir) {
					// FIXME: This is a package outside of the project we're
					// scanning. It should really be on vendor. But we don't
					// want it to reference GOPATH. We want it to be detected
					// and moved.
					l.PushBack(filepath.Join(r.VendorDir, filepath.FromSlash(imp)))
				}
			case LocRelative:
				if strings.HasPrefix(imp, "./"+gpath.VendorDir) {
					msg.Warn("Go package resolving will resolve %s without the ./%s/ prefix", imp, gpath.VendorDir)
				}
			}
		}

		if r.ResolveTest {
			for _, imp := range testImps {
				if talreadySeen[imp] {
					continue
				}
				talreadySeen[imp] = true
				info := r.FindPkg(imp)
				switch info.Loc {
				case LocUnknown, LocVendor:
					tl.PushBack(filepath.Join(r.VendorDir, filepath.FromSlash(imp))) // Do we need a path on this?
				case LocGopath:
					if !dirHasPrefix(info.Path, r.basedir) {
						// FIXME: This is a package outside of the project we're
						// scanning. It should really be on vendor. But we don't
						// want it to reference GOPATH. We want it to be detected
						// and moved.
						tl.PushBack(filepath.Join(r.VendorDir, filepath.FromSlash(imp)))
					}
				case LocRelative:
					if strings.HasPrefix(imp, "./"+gpath.VendorDir) {
						msg.Warn("Go package resolving will resolve %s without the ./%s/ prefix", imp, gpath.VendorDir)
					}
				}
			}
		}

		return nil
	})

	if err != nil {
		msg.Err("Failed to build an initial list of packages to scan: %s", err)
		return []string{}, []string{}, err
	}

	if deep {
		if r.ResolveAllFiles {
			re, err := r.resolveList(l, false, false)
			if err != nil {
				return []string{}, []string{}, err
			}
			tre, err := r.resolveList(l, false, true)
			return re, tre, err
		}
		re, err := r.resolveImports(l, false, false)
		if err != nil {
			return []string{}, []string{}, err
		}
		tre, err := r.resolveImports(tl, true, true)
		return re, tre, err
	}

	// If we're not doing a deep scan, we just convert the list into an
	// array and return.
	res := make([]string, 0, l.Len())
	for e := l.Front(); e != nil; e = e.Next() {
		res = append(res, e.Value.(string))
	}
	tres := make([]string, 0, l.Len())
	if r.ResolveTest {
		for e := tl.Front(); e != nil; e = e.Next() {
			tres = append(tres, e.Value.(string))
		}
	}

	return res, tres, nil
}

// ResolveAll takes a list of packages and returns an inclusive list of all
// vendored dependencies.
//
// While this will scan all of the source code it can find, it will only return
// packages that were either explicitly passed in as deps, or were explicitly
// imported by the code.
//
// Packages that are either CGO or on GOROOT are ignored. Packages that are
// on GOPATH, but not vendored currently generate a warning.
//
// If one of the passed in packages does not exist in the vendor directory,
// an error is returned.
func (r *Resolver) ResolveAll(deps []*cfg.Dependency, addTest bool) ([]string, error) {

	queue := sliceToQueue(deps, r.VendorDir)

	if r.ResolveAllFiles {
		return r.resolveList(queue, false, addTest)
	}
	return r.resolveImports(queue, false, addTest)
}

// Stripv strips the vendor/ prefix from vendored packages.
func (r *Resolver) Stripv(str string) string {
	return strings.TrimPrefix(str, r.VendorDir+string(os.PathSeparator))
}

// vpath adds an absolute vendor path.
func (r *Resolver) vpath(str string) string {
	return filepath.Join(r.basedir, "vendor", str)
}

// resolveImports takes a list of existing packages and resolves their imports.
//
// It returns a list of all of the packages that it can determine are required
// for the given code to function.
//
// The expectation is that each item in the queue is an absolute path to a
// vendored package. This attempts to read that package, and then find
// its referenced packages. Those packages are then added to the list
// to be scanned next.
//
// The resolver's handler is used in the cases where a package cannot be
// located.
//
// testDeps specifies if the test dependencies should be resolved and addTest
// specifies if the dependencies should be added to the Config.DevImports. This
// is important because we may resolve normal dependencies of test deps and add
// them to the DevImports list.
func (r *Resolver) resolveImports(queue *list.List, testDeps, addTest bool) ([]string, error) {
	msg.Debug("Resolving import path")

	// When test deps passed in but not resolving return empty.
	if (testDeps || addTest) && !r.ResolveTest {
		return []string{}, nil
	}

	for e := queue.Front(); e != nil; e = e.Next() {
		vdep := e.Value.(string)
		dep := r.Stripv(vdep)
		// Check if marked in the Q and then explicitly mark it. We want to know
		// if it had previously been marked and ensure it for the future.

		_, foundQ := r.alreadyQ[dep]
		r.alreadyQ[dep] = true

		// If we've already encountered an error processing this dependency
		// skip it.
		_, foundErr := r.hadError[dep]
		if foundErr {
			continue
		}

		// Skip ignored packages
		if r.Config.HasIgnore(dep) {
			msg.Debug("Ignoring: %s", dep)
			continue
		}
		r.VersionHandler.Process(dep)
		// Here, we want to import the package and see what imports it has.
		msg.Debug("Trying to open %s", vdep)
		var imps []string
		pkg, err := r.BuildContext.ImportDir(r.Handler.PkgPath(dep), 0)
		if err != nil && strings.HasPrefix(err.Error(), "found packages ") {
			// If we got here it's because a package and multiple packages
			// declared. This is often because of an example with a package
			// or main but +build ignore as a build tag. In that case we
			// try to brute force the packages with a slower scan.
			msg.Debug("Using Iterative Scanning for %s", dep)
			if testDeps {
				_, imps, err = IterativeScan(r.Handler.PkgPath(dep))
			} else {
				imps, _, err = IterativeScan(r.Handler.PkgPath(dep))
			}

			if err != nil {
				msg.Err("Iterative scanning error %s: %s", dep, err)
				continue
			}
		} else if err != nil {
			errStr := err.Error()
			msg.Debug("ImportDir error on %s: %s", r.Handler.PkgPath(dep), err)
			if strings.HasPrefix(errStr, "no buildable Go source") {
				msg.Debug("No subpackages declared. Skipping %s.", dep)
				continue
			} else if os.IsNotExist(err) && !foundErr && !foundQ {
				// If the location doesn't exist, there hasn't already been an
				// error, it's not already been in the Q then try to fetch it.
				// When there's an error or it's already in the Q (it should be
				// fetched if it's marked in r.alreadyQ) we skip to make sure
				// not to get stuck in a recursion.

				// If the location doesn't exist try to fetch it.
				if ok, err2 := r.Handler.NotFound(dep, addTest); ok {
					r.alreadyQ[dep] = true

					// By adding to the queue it will get reprocessed now that
					// it exists.
					queue.PushBack(r.vpath(dep))
					r.VersionHandler.SetVersion(dep, addTest)
				} else if err2 != nil {
					r.hadError[dep] = true
					msg.Err("Error looking for %s: %s", dep, err2)
				} else {
					r.hadError[dep] = true
					// TODO (mpb): Should we toss this into a Handler to
					// see if this is on GOPATH and copy it?
					msg.Info("Not found in vendor/: %s (1)", dep)
				}
			} else if strings.Contains(errStr, "no such file or directory") {
				r.hadError[dep] = true
				msg.Err("Error scanning %s: %s", dep, err)
				msg.Err("This error means the referenced package was not found.")
				msg.Err("Missing file or directory errors usually occur when multiple packages")
				msg.Err("share a common dependency and the first reference encountered by the scanner")
				msg.Err("sets the version to one that does not contain a subpackage needed required")
				msg.Err("by another package that uses the shared dependency. Try setting a")
				msg.Err("version in your glide.yaml that works for all packages that share this")
				msg.Err("dependency.")
			} else {
				r.hadError[dep] = true
				msg.Err("Error scanning %s: %s", dep, err)
			}
			continue
		} else {
			if testDeps {
				imps = dedupeStrings(pkg.TestImports, pkg.XTestImports)
			} else {
				imps = pkg.Imports
			}

		}

		// Range over all of the identified imports and see which ones we
		// can locate.
		for _, imp := range imps {
			if r.Config.HasIgnore(imp) {
				msg.Debug("Ignoring: %s", imp)
				continue
			}
			pi := r.FindPkg(imp)
			if pi.Loc != LocCgo && pi.Loc != LocGoroot && pi.Loc != LocAppengine {
				msg.Debug("Package %s imports %s", dep, imp)
			}
			switch pi.Loc {
			case LocVendor:
				msg.Debug("In vendor: %s", imp)
				if _, ok := r.alreadyQ[imp]; !ok {
					msg.Debug("Marking %s to be scanned.", imp)
					r.alreadyQ[dep] = true
					queue.PushBack(r.vpath(imp))
					if err := r.Handler.InVendor(imp, addTest); err == nil {
						r.VersionHandler.SetVersion(imp, addTest)
					} else {
						msg.Warn("Error updating %s: %s", imp, err)
					}
				}
			case LocUnknown:
				msg.Debug("Missing %s. Trying to resolve.", imp)
				if ok, err := r.Handler.NotFound(imp, addTest); ok {
					r.alreadyQ[dep] = true
					queue.PushBack(r.vpath(imp))
					r.VersionHandler.SetVersion(imp, addTest)
				} else if err != nil {
					r.hadError[dep] = true
					msg.Err("Error looking for %s: %s", imp, err)
				} else {
					r.hadError[dep] = true
					msg.Err("Not found: %s (2)", imp)
				}
			case LocGopath:
				msg.Debug("Found on GOPATH, not vendor: %s", imp)
				if _, ok := r.alreadyQ[imp]; !ok {
					// Only scan it if it gets moved into vendor/
					if ok, _ := r.Handler.OnGopath(imp, addTest); ok {
						r.alreadyQ[dep] = true
						queue.PushBack(r.vpath(imp))
						r.VersionHandler.SetVersion(imp, addTest)
					}
				}
			}
		}

	}

	if len(r.hadError) > 0 {
		// Errors occured so we return.
		return []string{}, errors.New("Error resolving imports")
	}

	// FIXME: From here to the end is a straight copy of the resolveList() func.
	res := make([]string, 0, queue.Len())

	// In addition to generating a list
	for e := queue.Front(); e != nil; e = e.Next() {
		t := r.Stripv(e.Value.(string))
		root, sp := util.NormalizeName(t)

		// Skip ignored packages
		if r.Config.HasIgnore(e.Value.(string)) {
			msg.Debug("Ignoring: %s", e.Value.(string))
			continue
		}

		// TODO(mattfarina): Need to eventually support devImport
		existing := r.Config.Imports.Get(root)
		if existing == nil && addTest {
			existing = r.Config.DevImports.Get(root)
		}
		if existing != nil {
			if sp != "" && !existing.HasSubpackage(sp) {
				existing.Subpackages = append(existing.Subpackages, sp)
			}
		} else {
			newDep := &cfg.Dependency{
				Name: root,
			}
			if sp != "" {
				newDep.Subpackages = []string{sp}
			}

			if addTest {
				r.Config.DevImports = append(r.Config.DevImports, newDep)
			} else {
				r.Config.Imports = append(r.Config.Imports, newDep)
			}
		}
		res = append(res, t)
	}

	return res, nil
}

// resolveList takes a list and resolves it.
//
// This walks the entire file tree for the given dependencies, not just the
// parts that are imported directly. Using this will discover dependencies
// regardless of OS, and arch.
func (r *Resolver) resolveList(queue *list.List, testDeps, addTest bool) ([]string, error) {
	// When test deps passed in but not resolving return empty.
	if testDeps && !r.ResolveTest {
		return []string{}, nil
	}

	var failedDep string
	for e := queue.Front(); e != nil; e = e.Next() {
		dep := e.Value.(string)
		t := strings.TrimPrefix(dep, r.VendorDir+string(os.PathSeparator))
		if r.Config.HasIgnore(t) {
			msg.Debug("Ignoring: %s", t)
			continue
		}
		r.VersionHandler.Process(t)
		//msg.Warn("#### %s ####", dep)
		//msg.Info("Seen Count: %d", len(r.seen))
		// Catch the outtermost dependency.
		failedDep = dep
		err := filepath.Walk(dep, func(path string, fi os.FileInfo, err error) error {
			if err != nil && err != filepath.SkipDir {
				return err
			}

			// Skip files.
			if !fi.IsDir() {
				return nil
			}
			// Skip dirs that are not source.
			if !srcDir(fi) {
				//msg.Debug("Skip resource %s", fi.Name())
				return filepath.SkipDir
			}

			// Anything that comes through here has already been through
			// the queue.
			r.alreadyQ[path] = true
			e := r.queueUnseen(path, queue, testDeps, addTest)
			if err != nil {
				failedDep = path
				//msg.Err("Failed to fetch dependency %s: %s", path, err)
			}
			return e
		})
		if err != nil && err != filepath.SkipDir {
			msg.Err("Dependency %s failed to resolve: %s.", failedDep, err)
			return []string{}, err
		}
	}

	res := make([]string, 0, queue.Len())

	// In addition to generating a list
	for e := queue.Front(); e != nil; e = e.Next() {
		t := strings.TrimPrefix(e.Value.(string), r.VendorDir+string(os.PathSeparator))
		root, sp := util.NormalizeName(t)

		existing := r.Config.Imports.Get(root)
		if existing == nil && addTest {
			existing = r.Config.DevImports.Get(root)
		}

		if existing != nil {
			if sp != "" && !existing.HasSubpackage(sp) {
				existing.Subpackages = append(existing.Subpackages, sp)
			}
		} else {
			newDep := &cfg.Dependency{
				Name: root,
			}
			if sp != "" {
				newDep.Subpackages = []string{sp}
			}

			if addTest {
				r.Config.DevImports = append(r.Config.DevImports, newDep)
			} else {
				r.Config.Imports = append(r.Config.Imports, newDep)
			}
		}
		res = append(res, e.Value.(string))
	}

	return res, nil
}

// queueUnseenImports scans a package's imports and adds any new ones to the
// processing queue.
func (r *Resolver) queueUnseen(pkg string, queue *list.List, testDeps, addTest bool) error {
	// A pkg is marked "seen" as soon as we have inspected it the first time.
	// Seen means that we have added all of its imports to the list.

	// Already queued indicates that we've either already put it into the queue
	// or intentionally not put it in the queue for fatal reasons (e.g. no
	// buildable source).

	deps, err := r.imports(pkg, testDeps, addTest)
	if err != nil && !strings.HasPrefix(err.Error(), "no buildable Go source") {
		msg.Err("Could not find %s: %s", pkg, err)
		return err
		// NOTE: If we uncomment this, we get lots of "no buildable Go source" errors,
		// which don't ever seem to be helpful. They don't actually indicate an error
		// condition, and it's perfectly okay to run into that condition.
		//} else if err != nil {
		//	msg.Warn(err.Error())
	}

	for _, d := range deps {
		if _, ok := r.alreadyQ[d]; !ok {
			r.alreadyQ[d] = true
			queue.PushBack(d)
		}
	}
	return nil
}

// imports gets all of the imports for a given package.
//
// If the package is in GOROOT, this will return an empty list (but not
// an error).
// If it cannot resolve the pkg, it will return an error.
func (r *Resolver) imports(pkg string, testDeps, addTest bool) ([]string, error) {

	if r.Config.HasIgnore(pkg) {
		msg.Debug("Ignoring %s", pkg)
		return []string{}, nil
	}

	// If this pkg is marked seen, we don't scan it again.
	if _, ok := r.seen[pkg]; ok {
		msg.Debug("Already saw %s", pkg)
		return []string{}, nil
	}

	// FIXME: On error this should try to NotFound to the dependency, and then import
	// it again.
	var imps []string
	p, err := r.BuildContext.ImportDir(r.Handler.PkgPath(pkg), 0)
	if err != nil && strings.HasPrefix(err.Error(), "found packages ") {
		// If we got here it's because a package and multiple packages
		// declared. This is often because of an example with a package
		// or main but +build ignore as a build tag. In that case we
		// try to brute force the packages with a slower scan.
		if testDeps {
			_, imps, err = IterativeScan(r.Handler.PkgPath(pkg))
		} else {
			imps, _, err = IterativeScan(r.Handler.PkgPath(pkg))
		}

		if err != nil {
			return []string{}, err
		}
	} else if err != nil {
		return []string{}, err
	} else {
		if testDeps {
			imps = dedupeStrings(p.TestImports, p.XTestImports)
		} else {
			imps = p.Imports
		}
	}

	// It is okay to scan a package more than once. In some cases, this is
	// desirable because the package can change between scans (e.g. as a result
	// of a failed scan resolving the situation).
	msg.Debug("=> Scanning %s (%s)", p.ImportPath, pkg)
	r.seen[pkg] = true

	// Optimization: If it's in GOROOT, it has no imports worth scanning.
	if p.Goroot {
		return []string{}, nil
	}

	// We are only looking for dependencies in vendor. No root, cgo, etc.
	buf := []string{}
	for _, imp := range imps {
		if r.Config.HasIgnore(imp) {
			msg.Debug("Ignoring %s", imp)
			continue
		}
		info := r.FindPkg(imp)
		switch info.Loc {
		case LocUnknown:
			// Do we resolve here?
			found, err := r.Handler.NotFound(imp, addTest)
			if err != nil {
				msg.Err("Failed to fetch %s: %s", imp, err)
			}
			if found {
				buf = append(buf, filepath.Join(r.VendorDir, filepath.FromSlash(imp)))
				r.VersionHandler.SetVersion(imp, addTest)
				continue
			}
			r.seen[info.Path] = true
		case LocVendor:
			//msg.Debug("Vendored: %s", imp)
			buf = append(buf, info.Path)
			if err := r.Handler.InVendor(imp, addTest); err == nil {
				r.VersionHandler.SetVersion(imp, addTest)
			} else {
				msg.Warn("Error updating %s: %s", imp, err)
			}
		case LocGopath:
			found, err := r.Handler.OnGopath(imp, addTest)
			if err != nil {
				msg.Err("Failed to fetch %s: %s", imp, err)
			}
			// If the Handler marks this as found, we drop it into the buffer
			// for subsequent processing. Otherwise, we assume that we're
			// in a less-than-perfect, but functional, situation.
			if found {
				buf = append(buf, filepath.Join(r.VendorDir, filepath.FromSlash(imp)))
				r.VersionHandler.SetVersion(imp, addTest)
				continue
			}
			msg.Warn("Package %s is on GOPATH, but not vendored. Ignoring.", imp)
			r.seen[info.Path] = true
		default:
			// Local packages are an odd case. CGO cannot be scanned.
			msg.Debug("===> Skipping %s", imp)
		}
	}

	return buf, nil
}

// sliceToQueue is a special-purpose function for unwrapping a slice of
// dependencies into a queue of fully qualified paths.
func sliceToQueue(deps []*cfg.Dependency, basepath string) *list.List {
	l := list.New()
	for _, e := range deps {
		if len(e.Subpackages) > 0 {
			for _, v := range e.Subpackages {
				ip := e.Name
				if v != "." && v != "" {
					ip = ip + "/" + v
				}
				msg.Debug("Adding local Import %s to queue", ip)
				l.PushBack(filepath.Join(basepath, filepath.FromSlash(ip)))
			}
		} else {
			msg.Debug("Adding local Import %s to queue", e.Name)
			l.PushBack(filepath.Join(basepath, filepath.FromSlash(e.Name)))
		}

	}
	return l
}

// PkgLoc describes the location of the package.
type PkgLoc uint8

const (
	// LocUnknown indicates the package location is unknown (probably not present)
	LocUnknown PkgLoc = iota
	// LocLocal inidcates that the package is in a local dir, not GOPATH or GOROOT.
	LocLocal
	// LocVendor indicates that the package is in a vendor/ dir
	LocVendor
	// LocGopath inidcates that the package is in GOPATH
	LocGopath
	// LocGoroot indicates that the package is in GOROOT
	LocGoroot
	// LocCgo indicates that the package is a a CGO package
	LocCgo
	// LocAppengine indicates the package is part of the appengine SDK. It's a
	// special build mode. https://blog.golang.org/the-app-engine-sdk-and-workspaces-gopath
	// Why does a Google product get a special case build mode with a local
	// package?
	LocAppengine
	// LocRelative indicates the package is a relative directory
	LocRelative
)

// PkgInfo represents metadata about a package found by the resolver.
type PkgInfo struct {
	Name, Path string
	Vendored   bool
	Loc        PkgLoc
}

// FindPkg takes a package name and attempts to find it on the filesystem
//
// The resulting PkgInfo will indicate where it was found.
func (r *Resolver) FindPkg(name string) *PkgInfo {
	// We cachae results for FindPkg to reduce the number of filesystem ops
	// that we have to do. This is a little risky because certain directories,
	// like GOPATH, can be modified while we're running an operation, and
	// render the cache inaccurate.
	//
	// Unfound items (LocUnknown) are never cached because we assume that as
	// part of the response, the Resolver may fetch that dependency.
	if i, ok := r.findCache[name]; ok {
		//msg.Info("Cache hit on %s", name)
		return i
	}

	// 502 individual packages scanned.
	// No cache:
	// glide -y etcd.yaml list  0.27s user 0.19s system 85% cpu 0.534 total
	// With cache:
	// glide -y etcd.yaml list  0.22s user 0.15s system 85% cpu 0.438 total

	var p string
	info := &PkgInfo{
		Name: name,
	}

	if strings.HasPrefix(name, "./") || strings.HasPrefix(name, "../") {
		info.Loc = LocRelative
		r.findCache[name] = info
		return info
	}

	// Check _only_ if this dep is in the current vendor directory.
	p = filepath.Join(r.VendorDir, filepath.FromSlash(name))
	if pkgExists(p) {
		info.Path = p
		info.Loc = LocVendor
		info.Vendored = true
		r.findCache[name] = info
		return info
	}

	// TODO: Do we need this if we always flatten?
	// Recurse backward to scan other vendor/ directories
	//for wd := cwd; wd != "/"; wd = filepath.Dir(wd) {
	//p = filepath.Join(wd, "vendor", filepath.FromSlash(name))
	//if fi, err = os.Stat(p); err == nil && (fi.IsDir() || isLink(fi)) {
	//info.Path = p
	//info.PType = ptypeVendor
	//info.Vendored = true
	//return info
	//}
	//}

	// Check $GOPATH
	for _, rr := range filepath.SplitList(r.BuildContext.GOPATH) {
		p = filepath.Join(rr, "src", filepath.FromSlash(name))
		if pkgExists(p) {
			info.Path = p
			info.Loc = LocGopath
			r.findCache[name] = info
			return info
		}
	}

	// Check $GOROOT
	for _, rr := range filepath.SplitList(r.BuildContext.GOROOT) {
		p = filepath.Join(rr, "src", filepath.FromSlash(name))
		if pkgExists(p) {
			info.Path = p
			info.Loc = LocGoroot
			r.findCache[name] = info
			return info
		}
	}

	// If this is "C", we're dealing with cgo
	if name == "C" {
		info.Loc = LocCgo
		r.findCache[name] = info
	} else if name == "appengine" || name == "appengine_internal" ||
		strings.HasPrefix(name, "appengine/") ||
		strings.HasPrefix(name, "appengine_internal/") {
		// Appengine is a special case when it comes to Go builds. It is a local
		// looking package only available within appengine. It's a special case
		// where Google products are playing with each other.
		// https://blog.golang.org/the-app-engine-sdk-and-workspaces-gopath
		info.Loc = LocAppengine
		r.findCache[name] = info
	} else if name == "context" || name == "net/http/httptrace" {
		// context and net/http/httptrace are packages being added to
		// the Go 1.7 standard library. Some packages, such as golang.org/x/net
		// are importing it with build flags in files for go1.7. Need to detect
		// this and handle it.
		info.Loc = LocGoroot
		r.findCache[name] = info
	}

	return info
}

func pkgExists(path string) bool {
	fi, err := os.Stat(path)
	return err == nil && (fi.IsDir() || isLink(fi))
}

// isLink returns true if the given FileInfo is a symbolic link.
func isLink(fi os.FileInfo) bool {
	return fi.Mode()&os.ModeSymlink == os.ModeSymlink
}

// IsSrcDir returns true if this is a directory that could have source code,
// false otherwise.
//
// Directories with _ or . prefixes are skipped, as are testdata and vendor.
func IsSrcDir(fi os.FileInfo) bool {
	return srcDir(fi)
}

func srcDir(fi os.FileInfo) bool {
	if !fi.IsDir() {
		return false
	}

	// Ignore _foo and .foo
	if strings.HasPrefix(fi.Name(), "_") || strings.HasPrefix(fi.Name(), ".") {
		return false
	}

	// Ignore testdata. For now, ignore vendor.
	if fi.Name() == "testdata" || fi.Name() == "vendor" {
		return false
	}

	return true
}

// checkForBasedirSymlink checks to see if the given basedir is actually a
// symlink. In the case that it is a symlink, the symlink is read and returned.
// If the basedir is not a symlink, the provided basedir argument is simply
// returned back to the caller.
func checkForBasedirSymlink(basedir string) (string, error) {
	fi, err := os.Lstat(basedir)
	if err != nil {
		return "", err
	}

	if fi.Mode()&os.ModeSymlink != 0 {
		return os.Readlink(basedir)
	}

	return basedir, nil
}

// helper func to merge, dedupe, and sort strings
func dedupeStrings(s1, s2 []string) (r []string) {
	dedupe := make(map[string]bool)

	if len(s1) > 0 && len(s2) > 0 {
		for _, i := range s1 {
			dedupe[i] = true
		}
		for _, i := range s2 {
			dedupe[i] = true
		}

		for i := range dedupe {
			r = append(r, i)
		}
		// And then re-sort them
		sort.Strings(r)
	} else if len(s1) > 0 {
		r = s1
	} else if len(s2) > 0 {
		r = s2
	}

	return
}
