// Copyright 2013 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 main

import (
	"fmt"
	"go/token"
	"go/types"

	"golang.org/x/tools/cmd/guru/serial"
	"golang.org/x/tools/go/callgraph"
	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/ssa"
	"golang.org/x/tools/go/ssa/ssautil"
)

// The callers function reports the possible callers of the function
// immediately enclosing the specified source location.
//
func callers(q *Query) error {
	lconf := loader.Config{Build: q.Build}

	if err := setPTAScope(&lconf, q.Scope); err != nil {
		return err
	}

	// Load/parse/type-check the program.
	lprog, err := loadWithSoftErrors(&lconf)
	if err != nil {
		return err
	}

	qpos, err := parseQueryPos(lprog, q.Pos, false)
	if err != nil {
		return err
	}

	prog := ssautil.CreateProgram(lprog, 0)

	ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
	if err != nil {
		return err
	}

	pkg := prog.Package(qpos.info.Pkg)
	if pkg == nil {
		return fmt.Errorf("no SSA package")
	}
	if !ssa.HasEnclosingFunction(pkg, qpos.path) {
		return fmt.Errorf("this position is not inside a function")
	}

	// Defer SSA construction till after errors are reported.
	prog.Build()

	target := ssa.EnclosingFunction(pkg, qpos.path)
	if target == nil {
		return fmt.Errorf("no SSA function built for this location (dead code?)")
	}

	// If the function is never address-taken, all calls are direct
	// and can be found quickly by inspecting the whole SSA program.
	cg := directCallsTo(target, entryPoints(ptaConfig.Mains))
	if cg == nil {
		// Run the pointer analysis, recording each
		// call found to originate from target.
		// (Pointer analysis may return fewer results than
		// directCallsTo because it ignores dead code.)
		ptaConfig.BuildCallGraph = true
		cg = ptrAnalysis(ptaConfig).CallGraph
	}
	cg.DeleteSyntheticNodes()
	edges := cg.CreateNode(target).In

	// TODO(adonovan): sort + dedup calls to ensure test determinism.

	q.Output(lprog.Fset, &callersResult{
		target:    target,
		callgraph: cg,
		edges:     edges,
	})
	return nil
}

// directCallsTo inspects the whole program and returns a callgraph
// containing edges for all direct calls to the target function.
// directCallsTo returns nil if the function is ever address-taken.
func directCallsTo(target *ssa.Function, entrypoints []*ssa.Function) *callgraph.Graph {
	cg := callgraph.New(nil) // use nil as root *Function
	targetNode := cg.CreateNode(target)

	// Is the function a program entry point?
	// If so, add edge from callgraph root.
	for _, f := range entrypoints {
		if f == target {
			callgraph.AddEdge(cg.Root, nil, targetNode)
		}
	}

	// Find receiver type (for methods).
	var recvType types.Type
	if recv := target.Signature.Recv(); recv != nil {
		recvType = recv.Type()
	}

	// Find all direct calls to function,
	// or a place where its address is taken.
	var space [32]*ssa.Value // preallocate
	for fn := range ssautil.AllFunctions(target.Prog) {
		for _, b := range fn.Blocks {
			for _, instr := range b.Instrs {
				// Is this a method (T).f of a concrete type T
				// whose runtime type descriptor is address-taken?
				// (To be fully sound, we would have to check that
				// the type doesn't make it to reflection as a
				// subelement of some other address-taken type.)
				if recvType != nil {
					if mi, ok := instr.(*ssa.MakeInterface); ok {
						if types.Identical(mi.X.Type(), recvType) {
							return nil // T is address-taken
						}
						if ptr, ok := mi.X.Type().(*types.Pointer); ok &&
							types.Identical(ptr.Elem(), recvType) {
							return nil // *T is address-taken
						}
					}
				}

				// Direct call to target?
				rands := instr.Operands(space[:0])
				if site, ok := instr.(ssa.CallInstruction); ok &&
					site.Common().Value == target {
					callgraph.AddEdge(cg.CreateNode(fn), site, targetNode)
					rands = rands[1:] // skip .Value (rands[0])
				}

				// Address-taken?
				for _, rand := range rands {
					if rand != nil && *rand == target {
						return nil
					}
				}
			}
		}
	}

	return cg
}

func entryPoints(mains []*ssa.Package) []*ssa.Function {
	var entrypoints []*ssa.Function
	for _, pkg := range mains {
		entrypoints = append(entrypoints, pkg.Func("init"))
		if main := pkg.Func("main"); main != nil && pkg.Pkg.Name() == "main" {
			entrypoints = append(entrypoints, main)
		}
	}
	return entrypoints
}

type callersResult struct {
	target    *ssa.Function
	callgraph *callgraph.Graph
	edges     []*callgraph.Edge
}

func (r *callersResult) PrintPlain(printf printfFunc) {
	root := r.callgraph.Root
	if r.edges == nil {
		printf(r.target, "%s is not reachable in this program.", r.target)
	} else {
		printf(r.target, "%s is called from these %d sites:", r.target, len(r.edges))
		for _, edge := range r.edges {
			if edge.Caller == root {
				printf(r.target, "the root of the call graph")
			} else {
				printf(edge, "\t%s from %s", edge.Description(), edge.Caller.Func)
			}
		}
	}
}

func (r *callersResult) JSON(fset *token.FileSet) []byte {
	var callers []serial.Caller
	for _, edge := range r.edges {
		callers = append(callers, serial.Caller{
			Caller: edge.Caller.Func.String(),
			Pos:    fset.Position(edge.Pos()).String(),
			Desc:   edge.Description(),
		})
	}
	return toJSON(callers)
}
