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

// This file defines oracle.Query, the entry point for the oracle tool.
// The actual executable is defined in cmd/oracle.

// TODO(adonovan): new query: show all statements that may update the
// selected lvalue (local, global, field, etc).

import (
	"bytes"
	encjson "encoding/json"
	"errors"
	"fmt"
	"go/ast"
	"go/build"
	"go/printer"
	"go/token"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"code.google.com/p/go.tools/go/types"
	"code.google.com/p/go.tools/importer"
	"code.google.com/p/go.tools/oracle/json"
	"code.google.com/p/go.tools/pointer"
	"code.google.com/p/go.tools/ssa"
)

type oracle struct {
	out    io.Writer      // standard output
	prog   *ssa.Program   // the SSA program [only populated if need&SSA]
	config pointer.Config // pointer analysis configuration

	// need&(Pos|ExactPos):
	startPos, endPos token.Pos             // source extent of query
	queryPkgInfo     *importer.PackageInfo // type info for the queried package
	queryPath        []ast.Node            // AST path from query node to root of ast.File

	// need&AllTypeInfo
	typeInfo map[*types.Package]*importer.PackageInfo // type info for all ASTs in the program

	timers map[string]time.Duration // phase timing information
}

// A set of bits indicating the analytical requirements of each mode.
//
// Typed ASTs for the whole program are always constructed
// transiently; they are retained only for the queried package unless
// AllTypeInfo is set.
const (
	Pos         = 1 << iota // needs a position
	ExactPos                // needs an exact AST selection; implies Pos
	AllTypeInfo             // needs to retain type info for all ASTs in the program
	SSA                     // needs ssa.Packages for whole program
	PTA         = SSA       // needs pointer analysis
)

type modeInfo struct {
	needs int
	impl  func(*oracle) (queryResult, error)
}

var modes = map[string]modeInfo{
	"callees":    modeInfo{PTA | ExactPos, callees},
	"callers":    modeInfo{PTA | Pos, callers},
	"callgraph":  modeInfo{PTA, callgraph},
	"callstack":  modeInfo{PTA | Pos, callstack},
	"describe":   modeInfo{PTA | ExactPos, describe},
	"freevars":   modeInfo{Pos, freevars},
	"implements": modeInfo{Pos, implements},
	"peers":      modeInfo{PTA | Pos, peers},
	"referrers":  modeInfo{AllTypeInfo | Pos, referrers},
}

type printfFunc func(pos interface{}, format string, args ...interface{})

// queryResult is the interface of each query-specific result type.
type queryResult interface {
	toJSON(res *json.Result, fset *token.FileSet)
	display(printf printfFunc)
}

type warning struct {
	pos    token.Pos
	format string
	args   []interface{}
}

// A Result encapsulates the result of an oracle.Query.
//
// Result instances implement the json.Marshaler interface, i.e. they
// can be JSON-serialized.
type Result struct {
	fset *token.FileSet
	// fprintf is a closure over the oracle's fileset and start/end position.
	fprintf  func(w io.Writer, pos interface{}, format string, args ...interface{})
	q        queryResult // the query-specific result
	mode     string      // query mode
	warnings []warning   // pointer analysis warnings
}

func (res *Result) MarshalJSON() ([]byte, error) {
	resj := &json.Result{Mode: res.mode}
	res.q.toJSON(resj, res.fset)
	for _, w := range res.warnings {
		resj.Warnings = append(resj.Warnings, json.PTAWarning{
			Pos:     res.fset.Position(w.pos).String(),
			Message: fmt.Sprintf(w.format, w.args...),
		})
	}
	return encjson.Marshal(resj)
}

// Query runs the oracle.
// args specify the main package in importer.CreatePackageFromArgs syntax.
// mode is the query mode ("callers", etc).
// pos is the selection in parseQueryPos() syntax.
// ptalog is the (optional) pointer-analysis log file.
// buildContext is the optional configuration for locating packages.
//
func Query(args []string, mode, pos string, ptalog io.Writer, buildContext *build.Context) (*Result, error) {
	minfo, ok := modes[mode]
	if !ok {
		if mode == "" {
			return nil, errors.New("you must specify a -mode of query to perform")
		}
		return nil, fmt.Errorf("invalid mode type: %q", mode)
	}

	imp := importer.New(&importer.Config{Build: buildContext})
	o := &oracle{
		prog:   ssa.NewProgram(imp.Fset, 0),
		timers: make(map[string]time.Duration),
	}
	o.config.Log = ptalog

	var res Result
	o.config.Warn = func(pos token.Pos, format string, args ...interface{}) {
		res.warnings = append(res.warnings, warning{pos, format, args})
	}

	// Phase timing diagnostics.
	if false {
		defer func() {
			fmt.Println()
			for name, duration := range o.timers {
				fmt.Printf("# %-30s %s\n", name, duration)
			}
		}()
	}

	// Load/parse/type-check program from args.
	start := time.Now()
	initialPkgInfos, args, err := imp.LoadInitialPackages(args)
	if err != nil {
		return nil, err // I/O or parser error
	}
	if len(args) > 0 {
		return nil, fmt.Errorf("surplus arguments: %q", args)
	}
	o.timers["load/parse/type"] = time.Since(start)

	// Retain type info for all ASTs in the program.
	if minfo.needs&AllTypeInfo != 0 {
		m := make(map[*types.Package]*importer.PackageInfo)
		for _, p := range imp.AllPackages() {
			m[p.Pkg] = p
		}
		o.typeInfo = m
	}

	// Parse the source query position.
	if minfo.needs&(Pos|ExactPos) != 0 {
		var err error
		o.startPos, o.endPos, err = parseQueryPos(o.prog.Fset, pos)
		if err != nil {
			return nil, err
		}

		var exact bool
		o.queryPkgInfo, o.queryPath, exact = imp.PathEnclosingInterval(o.startPos, o.endPos)
		if o.queryPath == nil {
			return nil, o.errorf(false, "no syntax here")
		}
		if minfo.needs&ExactPos != 0 && !exact {
			return nil, o.errorf(o.queryPath[0], "ambiguous selection within %s",
				importer.NodeDescription(o.queryPath[0]))
		}
	}

	// Create SSA package for the initial package and its dependencies.
	if minfo.needs&SSA != 0 {
		start = time.Now()

		// Create SSA packages.
		if err := o.prog.CreatePackages(imp); err != nil {
			return nil, o.errorf(false, "%s", err)
		}

		// Initial packages (specified on command line)
		for _, info := range initialPkgInfos {
			initialPkg := o.prog.Package(info.Pkg)

			// Add package to the pointer analysis scope.
			if initialPkg.Func("main") == nil {
				// TODO(adonovan): to simulate 'go test' more faithfully, we
				// should build a single synthetic testmain package,
				// not synthetic main functions to many packages.
				if initialPkg.CreateTestMainFunction() == nil {
					return nil, o.errorf(false, "analysis scope has no main() entry points")
				}
			}
			o.config.Mains = append(o.config.Mains, initialPkg)
		}

		// Query package.
		if o.queryPkgInfo != nil {
			pkg := o.prog.Package(o.queryPkgInfo.Pkg)
			pkg.SetDebugMode(true)
			pkg.Build()
		}

		o.timers["SSA-create"] = time.Since(start)
	}

	// SSA is built and we have query{Path,PkgInfo}.
	// Release the other ASTs and type info to the GC.
	imp = nil

	res.q, err = minfo.impl(o)
	if err != nil {
		return nil, err
	}
	res.mode = mode
	res.fset = o.prog.Fset
	res.fprintf = o.fprintf // captures o.prog, o.{start,end}Pos for later printing
	return &res, nil
}

// WriteTo writes the oracle query result res to out in a compiler diagnostic format.
func (res *Result) WriteTo(out io.Writer) {
	printf := func(pos interface{}, format string, args ...interface{}) {
		res.fprintf(out, pos, format, args...)
	}
	res.q.display(printf)

	// Print warnings after the main output.
	if res.warnings != nil {
		fmt.Fprintln(out, "\nPointer analysis warnings:")
		for _, w := range res.warnings {
			printf(w.pos, "warning: "+w.format, w.args...)
		}
	}
}

// ---------- Utilities ----------

// buildSSA constructs the SSA representation of Go-source function bodies.
// Not needed in simpler modes, e.g. freevars.
//
func buildSSA(o *oracle) {
	start := time.Now()
	o.prog.BuildAll()
	o.timers["SSA-build"] = time.Since(start)
}

// ptrAnalysis runs the pointer analysis and returns the synthetic
// root of the callgraph.
//
func ptrAnalysis(o *oracle) pointer.CallGraphNode {
	start := time.Now()
	root := pointer.Analyze(&o.config)
	o.timers["pointer analysis"] = time.Since(start)
	return root
}

// parseOctothorpDecimal returns the numeric value if s matches "#%d",
// otherwise -1.
func parseOctothorpDecimal(s string) int {
	if s != "" && s[0] == '#' {
		if s, err := strconv.ParseInt(s[1:], 10, 32); err == nil {
			return int(s)
		}
	}
	return -1
}

// parseQueryPos parses a string of the form "file:pos" or
// file:start,end" where pos, start, end match #%d and represent byte
// offsets, and returns the extent to which it refers.
//
// (Numbers without a '#' prefix are reserved for future use,
// e.g. to indicate line/column positions.)
//
func parseQueryPos(fset *token.FileSet, queryPos string) (start, end token.Pos, err error) {
	if queryPos == "" {
		err = fmt.Errorf("no source position specified (-pos flag)")
		return
	}

	colon := strings.LastIndex(queryPos, ":")
	if colon < 0 {
		err = fmt.Errorf("invalid source position -pos=%q", queryPos)
		return
	}
	filename, offset := queryPos[:colon], queryPos[colon+1:]
	startOffset := -1
	endOffset := -1
	if hyphen := strings.Index(offset, ","); hyphen < 0 {
		// e.g. "foo.go:#123"
		startOffset = parseOctothorpDecimal(offset)
		endOffset = startOffset
	} else {
		// e.g. "foo.go:#123,#456"
		startOffset = parseOctothorpDecimal(offset[:hyphen])
		endOffset = parseOctothorpDecimal(offset[hyphen+1:])
	}
	if startOffset < 0 || endOffset < 0 {
		err = fmt.Errorf("invalid -pos offset %q", offset)
		return
	}

	var file *token.File
	fset.Iterate(func(f *token.File) bool {
		if sameFile(filename, f.Name()) {
			// (f.Name() is absolute)
			file = f
			return false // done
		}
		return true // continue
	})
	if file == nil {
		err = fmt.Errorf("couldn't find file containing position -pos=%q", queryPos)
		return
	}

	// Range check [start..end], inclusive of both end-points.

	if 0 <= startOffset && startOffset <= file.Size() {
		start = file.Pos(int(startOffset))
	} else {
		err = fmt.Errorf("start position is beyond end of file -pos=%q", queryPos)
		return
	}

	if 0 <= endOffset && endOffset <= file.Size() {
		end = file.Pos(int(endOffset))
	} else {
		err = fmt.Errorf("end position is beyond end of file -pos=%q", queryPos)
		return
	}

	return
}

// sameFile returns true if x and y have the same basename and denote
// the same file.
//
func sameFile(x, y string) bool {
	if filepath.Base(x) == filepath.Base(y) { // (optimisation)
		if xi, err := os.Stat(x); err == nil {
			if yi, err := os.Stat(y); err == nil {
				return os.SameFile(xi, yi)
			}
		}
	}
	return false
}

// unparen returns e with any enclosing parentheses stripped.
func unparen(e ast.Expr) ast.Expr {
	for {
		p, ok := e.(*ast.ParenExpr)
		if !ok {
			break
		}
		e = p.X
	}
	return e
}

// deref returns a pointer's element type; otherwise it returns typ.
func deref(typ types.Type) types.Type {
	if p, ok := typ.Underlying().(*types.Pointer); ok {
		return p.Elem()
	}
	return typ
}

// fprintf prints to w a message of the form "location: message\n"
// where location is derived from pos.
//
// pos must be one of:
//    - a token.Pos, denoting a position
//    - an ast.Node, denoting an interval
//    - anything with a Pos() method:
//         ssa.Member, ssa.Value, ssa.Instruction, types.Object, pointer.Label, etc.
//    - a bool, meaning the extent [o.startPos, o.endPos) of the user's query.
//      (the value is ignored)
//    - nil, meaning no position at all.
//
// The output format is is compatible with the 'gnu'
// compilation-error-regexp in Emacs' compilation mode.
// TODO(adonovan): support other editors.
//
func (o *oracle) fprintf(w io.Writer, pos interface{}, format string, args ...interface{}) {
	var start, end token.Pos
	switch pos := pos.(type) {
	case ast.Node:
		start = pos.Pos()
		end = pos.End()
	case token.Pos:
		start = pos
		end = start
	case interface {
		Pos() token.Pos
	}:
		start = pos.Pos()
		end = start
	case bool:
		start = o.startPos
		end = o.endPos
	case nil:
		// no-op
	default:
		panic(fmt.Sprintf("invalid pos: %T", pos))
	}

	if sp := o.prog.Fset.Position(start); start == end {
		// (prints "-: " for token.NoPos)
		fmt.Fprintf(w, "%s: ", sp)
	} else {
		ep := o.prog.Fset.Position(end)
		// The -1 below is a concession to Emacs's broken use of
		// inclusive (not half-open) intervals.
		// Other editors may not want it.
		// TODO(adonovan): add an -editor=vim|emacs|acme|auto
		// flag; auto uses EMACS=t / VIM=... / etc env vars.
		fmt.Fprintf(w, "%s:%d.%d-%d.%d: ",
			sp.Filename, sp.Line, sp.Column, ep.Line, ep.Column-1)
	}
	fmt.Fprintf(w, format, args...)
	io.WriteString(w, "\n")
}

// errorf is like fprintf, but returns a formatted error string.
func (o *oracle) errorf(pos interface{}, format string, args ...interface{}) error {
	var buf bytes.Buffer
	o.fprintf(&buf, pos, format, args...)
	return errors.New(buf.String())
}

// printNode returns the pretty-printed syntax of n.
func (o *oracle) printNode(n ast.Node) string {
	var buf bytes.Buffer
	printer.Fprint(&buf, o.prog.Fset, n)
	return buf.String()
}
