// 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.

// +build go1.5

package analysis

// This file computes the CALLERS and CALLEES relations from the call
// graph.  CALLERS/CALLEES information is displayed in the lower pane
// when a "func" token or ast.CallExpr.Lparen is clicked, respectively.

import (
	"fmt"
	"go/ast"
	"go/token"
	"go/types"
	"log"
	"math/big"
	"sort"

	"golang.org/x/tools/go/callgraph"
	"golang.org/x/tools/go/ssa"
)

// doCallgraph computes the CALLEES and CALLERS relations.
func (a *analysis) doCallgraph(cg *callgraph.Graph) {
	log.Print("Deleting synthetic nodes...")
	// TODO(adonovan): opt: DeleteSyntheticNodes is asymptotically
	// inefficient and can be (unpredictably) slow.
	cg.DeleteSyntheticNodes()
	log.Print("Synthetic nodes deleted")

	// Populate nodes of package call graphs (PCGs).
	for _, n := range cg.Nodes {
		a.pcgAddNode(n.Func)
	}
	// Within each PCG, sort funcs by name.
	for _, pcg := range a.pcgs {
		pcg.sortNodes()
	}

	calledFuncs := make(map[ssa.CallInstruction]map[*ssa.Function]bool)
	callingSites := make(map[*ssa.Function]map[ssa.CallInstruction]bool)
	for _, n := range cg.Nodes {
		for _, e := range n.Out {
			if e.Site == nil {
				continue // a call from a synthetic node such as <root>
			}

			// Add (site pos, callee) to calledFuncs.
			// (Dynamic calls only.)
			callee := e.Callee.Func

			a.pcgAddEdge(n.Func, callee)

			if callee.Synthetic != "" {
				continue // call of a package initializer
			}

			if e.Site.Common().StaticCallee() == nil {
				// dynamic call
				// (CALLEES information for static calls
				// is computed using SSA information.)
				lparen := e.Site.Common().Pos()
				if lparen != token.NoPos {
					fns := calledFuncs[e.Site]
					if fns == nil {
						fns = make(map[*ssa.Function]bool)
						calledFuncs[e.Site] = fns
					}
					fns[callee] = true
				}
			}

			// Add (callee, site) to callingSites.
			fns := callingSites[callee]
			if fns == nil {
				fns = make(map[ssa.CallInstruction]bool)
				callingSites[callee] = fns
			}
			fns[e.Site] = true
		}
	}

	// CALLEES.
	log.Print("Callees...")
	for site, fns := range calledFuncs {
		var funcs funcsByPos
		for fn := range fns {
			funcs = append(funcs, fn)
		}
		sort.Sort(funcs)

		a.addCallees(site, funcs)
	}

	// CALLERS
	log.Print("Callers...")
	for callee, sites := range callingSites {
		pos := funcToken(callee)
		if pos == token.NoPos {
			log.Printf("CALLERS: skipping %s: no pos", callee)
			continue
		}

		var this *types.Package // for relativizing names
		if callee.Pkg != nil {
			this = callee.Pkg.Pkg
		}

		// Compute sites grouped by parent, with text and URLs.
		sitesByParent := make(map[*ssa.Function]sitesByPos)
		for site := range sites {
			fn := site.Parent()
			sitesByParent[fn] = append(sitesByParent[fn], site)
		}
		var funcs funcsByPos
		for fn := range sitesByParent {
			funcs = append(funcs, fn)
		}
		sort.Sort(funcs)

		v := callersJSON{
			Callee:  callee.String(),
			Callers: []callerJSON{}, // (JS wants non-nil)
		}
		for _, fn := range funcs {
			caller := callerJSON{
				Func:  prettyFunc(this, fn),
				Sites: []anchorJSON{}, // (JS wants non-nil)
			}
			sites := sitesByParent[fn]
			sort.Sort(sites)
			for _, site := range sites {
				pos := site.Common().Pos()
				if pos != token.NoPos {
					caller.Sites = append(caller.Sites, anchorJSON{
						Text: fmt.Sprintf("%d", a.prog.Fset.Position(pos).Line),
						Href: a.posURL(pos, len("(")),
					})
				}
			}
			v.Callers = append(v.Callers, caller)
		}

		fi, offset := a.fileAndOffset(pos)
		fi.addLink(aLink{
			start:   offset,
			end:     offset + len("func"),
			title:   fmt.Sprintf("%d callers", len(sites)),
			onclick: fmt.Sprintf("onClickCallers(%d)", fi.addData(v)),
		})
	}

	// PACKAGE CALLGRAPH
	log.Print("Package call graph...")
	for pkg, pcg := range a.pcgs {
		// Maps (*ssa.Function).RelString() to index in JSON CALLGRAPH array.
		index := make(map[string]int)

		// Treat exported functions (and exported methods of
		// exported named types) as roots even if they aren't
		// actually called from outside the package.
		for i, n := range pcg.nodes {
			if i == 0 || n.fn.Object() == nil || !n.fn.Object().Exported() {
				continue
			}
			recv := n.fn.Signature.Recv()
			if recv == nil || deref(recv.Type()).(*types.Named).Obj().Exported() {
				roots := &pcg.nodes[0].edges
				roots.SetBit(roots, i, 1)
			}
			index[n.fn.RelString(pkg.Pkg)] = i
		}

		json := a.pcgJSON(pcg)

		// TODO(adonovan): pkg.Path() is not unique!
		// It is possible to declare a non-test package called x_test.
		a.result.pkgInfo(pkg.Pkg.Path()).setCallGraph(json, index)
	}
}

// addCallees adds client data and links for the facts that site calls fns.
func (a *analysis) addCallees(site ssa.CallInstruction, fns []*ssa.Function) {
	v := calleesJSON{
		Descr:   site.Common().Description(),
		Callees: []anchorJSON{}, // (JS wants non-nil)
	}
	var this *types.Package // for relativizing names
	if p := site.Parent().Package(); p != nil {
		this = p.Pkg
	}

	for _, fn := range fns {
		v.Callees = append(v.Callees, anchorJSON{
			Text: prettyFunc(this, fn),
			Href: a.posURL(funcToken(fn), len("func")),
		})
	}

	fi, offset := a.fileAndOffset(site.Common().Pos())
	fi.addLink(aLink{
		start:   offset,
		end:     offset + len("("),
		title:   fmt.Sprintf("%d callees", len(v.Callees)),
		onclick: fmt.Sprintf("onClickCallees(%d)", fi.addData(v)),
	})
}

// -- utilities --------------------------------------------------------

// stable order within packages but undefined across packages.
type funcsByPos []*ssa.Function

func (a funcsByPos) Less(i, j int) bool { return a[i].Pos() < a[j].Pos() }
func (a funcsByPos) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a funcsByPos) Len() int           { return len(a) }

type sitesByPos []ssa.CallInstruction

func (a sitesByPos) Less(i, j int) bool { return a[i].Common().Pos() < a[j].Common().Pos() }
func (a sitesByPos) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a sitesByPos) Len() int           { return len(a) }

func funcToken(fn *ssa.Function) token.Pos {
	switch syntax := fn.Syntax().(type) {
	case *ast.FuncLit:
		return syntax.Type.Func
	case *ast.FuncDecl:
		return syntax.Type.Func
	}
	return token.NoPos
}

// prettyFunc pretty-prints fn for the user interface.
// TODO(adonovan): return HTML so we have more markup freedom.
func prettyFunc(this *types.Package, fn *ssa.Function) string {
	if fn.Parent() != nil {
		return fmt.Sprintf("%s in %s",
			types.TypeString(fn.Signature, types.RelativeTo(this)),
			prettyFunc(this, fn.Parent()))
	}
	if fn.Synthetic != "" && fn.Name() == "init" {
		// (This is the actual initializer, not a declared 'func init').
		if fn.Pkg.Pkg == this {
			return "package initializer"
		}
		return fmt.Sprintf("%q package initializer", fn.Pkg.Pkg.Path())
	}
	return fn.RelString(this)
}

// -- intra-package callgraph ------------------------------------------

// pcgNode represents a node in the package call graph (PCG).
type pcgNode struct {
	fn     *ssa.Function
	pretty string  // cache of prettyFunc(fn)
	edges  big.Int // set of callee func indices
}

// A packageCallGraph represents the intra-package edges of the global call graph.
// The zeroth node indicates "all external functions".
type packageCallGraph struct {
	nodeIndex map[*ssa.Function]int // maps func to node index (a small int)
	nodes     []*pcgNode            // maps node index to node
}

// sortNodes populates pcg.nodes in name order and updates the nodeIndex.
func (pcg *packageCallGraph) sortNodes() {
	nodes := make([]*pcgNode, 0, len(pcg.nodeIndex))
	nodes = append(nodes, &pcgNode{fn: nil, pretty: "<external>"})
	for fn := range pcg.nodeIndex {
		nodes = append(nodes, &pcgNode{
			fn:     fn,
			pretty: prettyFunc(fn.Pkg.Pkg, fn),
		})
	}
	sort.Sort(pcgNodesByPretty(nodes[1:]))
	for i, n := range nodes {
		pcg.nodeIndex[n.fn] = i
	}
	pcg.nodes = nodes
}

func (pcg *packageCallGraph) addEdge(caller, callee *ssa.Function) {
	var callerIndex int
	if caller.Pkg == callee.Pkg {
		// intra-package edge
		callerIndex = pcg.nodeIndex[caller]
		if callerIndex < 1 {
			panic(caller)
		}
	}
	edges := &pcg.nodes[callerIndex].edges
	edges.SetBit(edges, pcg.nodeIndex[callee], 1)
}

func (a *analysis) pcgAddNode(fn *ssa.Function) {
	if fn.Pkg == nil {
		return
	}
	pcg, ok := a.pcgs[fn.Pkg]
	if !ok {
		pcg = &packageCallGraph{nodeIndex: make(map[*ssa.Function]int)}
		a.pcgs[fn.Pkg] = pcg
	}
	pcg.nodeIndex[fn] = -1
}

func (a *analysis) pcgAddEdge(caller, callee *ssa.Function) {
	if callee.Pkg != nil {
		a.pcgs[callee.Pkg].addEdge(caller, callee)
	}
}

// pcgJSON returns a new slice of callgraph JSON values.
func (a *analysis) pcgJSON(pcg *packageCallGraph) []*PCGNodeJSON {
	var nodes []*PCGNodeJSON
	for _, n := range pcg.nodes {

		// TODO(adonovan): why is there no good way to iterate
		// over the set bits of a big.Int?
		var callees []int
		nbits := n.edges.BitLen()
		for j := 0; j < nbits; j++ {
			if n.edges.Bit(j) == 1 {
				callees = append(callees, j)
			}
		}

		var pos token.Pos
		if n.fn != nil {
			pos = funcToken(n.fn)
		}
		nodes = append(nodes, &PCGNodeJSON{
			Func: anchorJSON{
				Text: n.pretty,
				Href: a.posURL(pos, len("func")),
			},
			Callees: callees,
		})
	}
	return nodes
}

type pcgNodesByPretty []*pcgNode

func (a pcgNodesByPretty) Less(i, j int) bool { return a[i].pretty < a[j].pretty }
func (a pcgNodesByPretty) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a pcgNodesByPretty) Len() int           { return len(a) }
