// 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 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"
	"log"
	"math/big"
	"sort"

	"code.google.com/p/go.tools/go/callgraph"
	"code.google.com/p/go.tools/go/ssa"
	"code.google.com/p/go.tools/go/types"
)

// 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 the <root> node
			}

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

		// 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.Object)] = 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.Object.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.Object
	}

	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.Enclosing != nil {
		return fmt.Sprintf("%s in %s",
			types.TypeString(this, fn.Signature),
			prettyFunc(this, fn.Enclosing))
	}
	if fn.Synthetic != "" && fn.Name() == "init" {
		// (This is the actual initializer, not a declared 'func init').
		if fn.Pkg.Object == this {
			return "package initializer"
		}
		return fmt.Sprintf("%q package initializer", fn.Pkg.Object.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.Object, 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) }
