// 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 importgraph computes the forward and reverse import
// dependency graphs for all packages in a Go workspace.
package importgraph

import (
	"go/build"
	"sync"

	"golang.org/x/tools/go/buildutil"
)

// A Graph is an import dependency graph, either forward or reverse.
//
// The graph maps each node (a package import path) to the set of its
// successors in the graph.  For a forward graph, this is the set of
// imported packages (prerequisites); for a reverse graph, it is the set
// of importing packages (clients).
//
type Graph map[string]map[string]bool

func (g Graph) addEdge(from, to string) {
	edges := g[from]
	if edges == nil {
		edges = make(map[string]bool)
		g[from] = edges
	}
	edges[to] = true
}

// Search returns all the nodes of the graph reachable from
// any of the specified roots, by following edges forwards.
// Relationally, this is the reflexive transitive closure.
func (g Graph) Search(roots ...string) map[string]bool {
	seen := make(map[string]bool)
	var visit func(x string)
	visit = func(x string) {
		if !seen[x] {
			seen[x] = true
			for y := range g[x] {
				visit(y)
			}
		}
	}
	for _, root := range roots {
		visit(root)
	}
	return seen
}

// Builds scans the specified Go workspace and builds the forward and
// reverse import dependency graphs for all its packages.
// It also returns a mapping from import paths to errors for packages
// that could not be loaded.
func Build(ctxt *build.Context) (forward, reverse Graph, errors map[string]error) {
	// The (sole) graph builder goroutine receives a stream of import
	// edges from the package loading goroutine.
	forward = make(Graph)
	reverse = make(Graph)
	edgec := make(chan [2]string)
	go func() {
		for edge := range edgec {
			if edge[1] == "C" {
				continue // "C" is fake
			}
			forward.addEdge(edge[0], edge[1])
			reverse.addEdge(edge[1], edge[0])
		}
	}()

	// The (sole) error goroutine receives a stream of ReadDir and
	// Import errors.
	type pathError struct {
		path string
		err  error
	}
	errorc := make(chan pathError)
	go func() {
		for e := range errorc {
			if errors == nil {
				errors = make(map[string]error)
			}
			errors[e.path] = e.err
		}
	}()

	var wg sync.WaitGroup
	buildutil.ForEachPackage(ctxt, func(path string, err error) {
		if err != nil {
			errorc <- pathError{path, err}
			return
		}
		wg.Add(1)
		// The import goroutines load the metadata for each package.
		go func(path string) {
			defer wg.Done()
			bp, err := ctxt.Import(path, "", 0)
			if _, ok := err.(*build.NoGoError); ok {
				return // empty directory is not an error
			}
			if err != nil {
				errorc <- pathError{path, err}
				return
			}
			for _, imp := range bp.Imports {
				edgec <- [2]string{path, imp}
			}
			for _, imp := range bp.TestImports {
				edgec <- [2]string{path, imp}
			}
			for _, imp := range bp.XTestImports {
				edgec <- [2]string{path, imp}
			}
		}(path)
	})
	wg.Wait()

	close(edgec)
	close(errorc)

	return forward, reverse, errors
}
