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

import (
	"fmt"
	"go/token"
	"io"

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

type Config struct {
	// -------- Scope of the analysis --------

	// Clients must provide the analysis with at least one package defining a main() function.
	Mains []*ssa.Package // set of 'main' packages to analyze
	root  *ssa.Function  // synthetic analysis root

	// -------- Optional callbacks invoked by the analysis --------

	// Call is invoked for each discovered call-graph edge.  The
	// call-graph is a multigraph over CallGraphNodes with edges
	// labelled by the CallSite that gives rise to the edge.
	// (The caller node is available as site.Caller())
	//
	// Clients that wish to construct a call graph may provide
	// CallGraph.AddEdge here.
	//
	// The callgraph may be context-sensitive, i.e. it may
	// distinguish separate calls to the same function depending
	// on the context.
	//
	Call func(site CallSite, callee CallGraphNode)

	// CallSite is invoked for each call-site encountered in the
	// program.
	//
	// The callgraph may be context-sensitive, i.e. it may
	// distinguish separate calls to the same function depending
	// on the context.
	//
	CallSite func(site CallSite)

	// Warn is invoked for each warning encountered by the analysis,
	// e.g. unknown external function, unsound use of unsafe.Pointer.
	// pos may be zero if the position is not known.
	Warn func(pos token.Pos, format string, args ...interface{})

	// Print is invoked during the analysis for each discovered
	// call to the built-in print(x).
	//
	// Pointer p may be saved until the analysis is complete, at
	// which point its methods provide access to the analysis
	// (The result of callings its methods within the Print
	// callback is undefined.)  p is nil if x is non-pointerlike.
	//
	// TODO(adonovan): this was a stop-gap measure for identifing
	// arbitrary expressions of interest in the tests.  Now that
	// ssa.ValueForExpr exists, we should use that instead.
	//
	Print func(site *ssa.CallCommon, p Pointer)

	// The client populates QueryValues[v] for each ssa.Value v
	// of interest.
	//
	// The boolean (Indirect) indicates whether to compute the
	// points-to set for v (false) or *v (true): the latter is
	// typically wanted for Values corresponding to source-level
	// lvalues, e.g. an *ssa.Global.
	//
	// The pointer analysis will populate the corresponding
	// QueryResults value when it creates the pointer variable
	// for v or *v.  Upon completion the client can inspect the
	// map for the results.
	//
	// If a Value belongs to a function that the analysis treats
	// context-sensitively, the corresponding QueryResults slice
	// may have multiple Pointers, one per distinct context.  Use
	// PointsToCombined to merge them.
	//
	// TODO(adonovan): refactor the API: separate all results of
	// Analyze() into a dedicated Result struct.
	//
	QueryValues  map[ssa.Value]Indirect
	QueryResults map[ssa.Value][]Pointer

	// -------- Other configuration options --------

	// If Log is non-nil, a log messages are written to it.
	// Logging is extremely verbose.
	Log io.Writer
}

type Indirect bool // map[ssa.Value]Indirect is not a set

func (c *Config) prog() *ssa.Program {
	for _, main := range c.Mains {
		return main.Prog
	}
	panic("empty scope")
}

// A Pointer is an equivalence class of pointerlike values.
//
// TODO(adonovan): add a method
//    Context() CallGraphNode
// for pointers corresponding to local variables,
//
type Pointer interface {
	// PointsTo returns the points-to set of this pointer.
	PointsTo() PointsToSet

	// MayAlias reports whether the receiver pointer may alias
	// the argument pointer.
	MayAlias(Pointer) bool

	String() string
}

// A PointsToSet is a set of labels (locations or allocations).
//
type PointsToSet interface {
	// PointsTo returns the set of labels that this points-to set
	// contains.
	Labels() []*Label

	// Intersects reports whether this points-to set and the
	// argument points-to set contain common members.
	Intersects(PointsToSet) bool

	// If this PointsToSet came from a Pointer of interface kind,
	// ConcreteTypes returns the set of concrete types the
	// interface may contain.
	//
	// The result is a mapping whose keys are the concrete types
	// to which this interface may point.  For each pointer-like
	// key type, the corresponding map value is a set of pointer
	// abstractions of that concrete type, represented as a
	// []Pointer slice.  Use PointsToCombined to merge them.
	ConcreteTypes() *typemap.M
}

// Union returns the set containing all the elements of each set in sets.
func Union(sets ...PointsToSet) PointsToSet {
	var union ptset
	for _, set := range sets {
		set := set.(ptset)
		union.a = set.a
		union.pts.addAll(set.pts)
	}
	return union
}

// PointsToCombined returns the combined points-to set of all the
// specified pointers.
func PointsToCombined(ptrs []Pointer) PointsToSet {
	var ptsets []PointsToSet
	for _, ptr := range ptrs {
		ptsets = append(ptsets, ptr.PointsTo())
	}
	return Union(ptsets...)
}

// ---- PointsToSet public interface

type ptset struct {
	a   *analysis // may be nil if pts is nil
	pts nodeset
}

func (s ptset) Labels() []*Label {
	var labels []*Label
	for l := range s.pts {
		// Scan back to the previous object start.
		for i := l; i >= 0; i-- {
			n := s.a.nodes[i]
			if n.flags&ntObject != 0 {
				// TODO(adonovan): do bounds-check against n.size.
				var v ssa.Value
				if n.flags&ntFunction != 0 {
					v = n.data.(*cgnode).fn
				} else {
					v = n.data.(ssa.Value)
					// TODO(adonovan): what if v is nil?
				}
				labels = append(labels, &Label{
					Value:      v,
					subelement: s.a.nodes[l].subelement,
				})
				break
			}
		}
	}
	return labels
}

func (s ptset) ConcreteTypes() *typemap.M {
	var tmap typemap.M // default hasher // TODO(adonovan): opt: memoize per analysis
	for ifaceObjId := range s.pts {
		if s.a.nodes[ifaceObjId].flags&ntInterface == 0 {
			// ConcreteTypes called on non-interface PT set.
			continue // shouldn't happen
		}
		v, tconc := s.a.interfaceValue(ifaceObjId)
		prev, _ := tmap.At(tconc).([]Pointer)
		tmap.Set(tconc, append(prev, ptr{s.a, v}))
	}
	return &tmap
}

func (x ptset) Intersects(y_ PointsToSet) bool {
	y := y_.(ptset)
	for l := range x.pts {
		if _, ok := y.pts[l]; ok {
			return true
		}
	}
	return false
}

// ---- Pointer public interface

// ptr adapts a node to the Pointer interface.
type ptr struct {
	a *analysis
	n nodeid // non-zero
}

func (p ptr) String() string {
	return fmt.Sprintf("n%d", p.n)
}

func (p ptr) PointsTo() PointsToSet {
	return ptset{p.a, p.a.nodes[p.n].pts}
}

func (p ptr) MayAlias(q Pointer) bool {
	return p.PointsTo().Intersects(q.PointsTo())
}

func (p ptr) ConcreteTypes() *typemap.M {
	return p.PointsTo().ConcreteTypes()
}
