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

// guru: a tool for answering questions about Go source code.
//
//    http://golang.org/s/using-guru
//
// Run with -help flag or help subcommand for usage information.
//
package main // import "golang.org/x/tools/cmd/guru"

import (
	"bufio"
	"flag"
	"fmt"
	"go/build"
	"go/token"
	"io"
	"log"
	"os"
	"runtime/pprof"
	"strings"
	"sync"

	"golang.org/x/tools/go/buildutil"
)

// flags
var (
	modifiedFlag   = flag.Bool("modified", false, "read archive of modified files from standard input")
	scopeFlag      = flag.String("scope", "", "comma-separated list of `packages` the analysis should be limited to")
	ptalogFlag     = flag.String("ptalog", "", "write points-to analysis log to `file`")
	jsonFlag       = flag.Bool("json", false, "emit output in JSON format")
	reflectFlag    = flag.Bool("reflect", false, "analyze reflection soundly (slow)")
	cpuprofileFlag = flag.String("cpuprofile", "", "write CPU profile to `file`")
)

func init() {
	flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
}

const useHelp = "Run 'guru -help' for more information.\n"

const helpMessage = `Go source code guru.
Usage: guru [flags] <mode> <position>

The mode argument determines the query to perform:

	callees	  	show possible targets of selected function call
	callers	  	show possible callers of selected function
	callstack 	show path from callgraph root to selected function
	definition	show declaration of selected identifier
	describe  	describe selected syntax: definition, methods, etc
	freevars  	show free variables of selection
	implements	show 'implements' relation for selected type or method
	peers     	show send/receive corresponding to selected channel op
	pointsto	show variables the selected pointer may point to
	referrers 	show all refs to entity denoted by selected identifier
	what		show basic information about the selected syntax node
	whicherrs	show possible values of the selected error variable

The position argument specifies the filename and byte offset (or range)
of the syntax element to query.  For example:

	foo.go:#123,#128
	bar.go:#123

The -json flag causes guru to emit output in JSON format;
	golang.org/x/tools/cmd/guru/serial defines its schema.
	Otherwise, the output is in an editor-friendly format in which
	every line has the form "pos: text", where pos is "-" if unknown.

The -modified flag causes guru to read an archive from standard input.
	Files in this archive will be used in preference to those in
	the file system.  In this way, a text editor may supply guru
	with the contents of its unsaved buffers.  Each archive entry
	consists of the file name, a newline, the decimal file size,
	another newline, and the contents of the file.

The -scope flag restricts analysis to the specified packages.
	Its value is a comma-separated list of patterns of these forms:
		golang.org/x/tools/cmd/guru     # a single package
		golang.org/x/tools/...          # all packages beneath dir
		...                             # the entire workspace.
	A pattern preceded by '-' is negative, so the scope
		encoding/...,-encoding/xml
	matches all encoding packages except encoding/xml.

User manual: http://golang.org/s/using-guru

Example: describe syntax at offset 530 in this file (an import spec):

  $ guru describe src/golang.org/x/tools/cmd/guru/main.go:#530
`

func printHelp() {
	fmt.Fprintln(os.Stderr, helpMessage)
	fmt.Fprintln(os.Stderr, "Flags:")
	flag.PrintDefaults()
}

func main() {
	log.SetPrefix("guru: ")
	log.SetFlags(0)

	// Don't print full help unless -help was requested.
	// Just gently remind users that it's there.
	flag.Usage = func() { fmt.Fprint(os.Stderr, useHelp) }
	flag.CommandLine.Init(os.Args[0], flag.ContinueOnError) // hack
	if err := flag.CommandLine.Parse(os.Args[1:]); err != nil {
		// (err has already been printed)
		if err == flag.ErrHelp {
			printHelp()
		}
		os.Exit(2)
	}

	args := flag.Args()
	if len(args) != 2 {
		flag.Usage()
		os.Exit(2)
	}
	mode, posn := args[0], args[1]

	if mode == "help" {
		printHelp()
		os.Exit(2)
	}

	// Set up points-to analysis log file.
	var ptalog io.Writer
	if *ptalogFlag != "" {
		if f, err := os.Create(*ptalogFlag); err != nil {
			log.Fatalf("Failed to create PTA log file: %s", err)
		} else {
			buf := bufio.NewWriter(f)
			ptalog = buf
			defer func() {
				if err := buf.Flush(); err != nil {
					log.Printf("flush: %s", err)
				}
				if err := f.Close(); err != nil {
					log.Printf("close: %s", err)
				}
			}()
		}
	}

	// Profiling support.
	if *cpuprofileFlag != "" {
		f, err := os.Create(*cpuprofileFlag)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	ctxt := &build.Default

	// If there were modified files,
	// read them from the standard input and
	// overlay them on the build context.
	if *modifiedFlag {
		modified, err := buildutil.ParseOverlayArchive(os.Stdin)
		if err != nil {
			log.Fatal(err)
		}

		// All I/O done by guru needs to consult the modified map.
		// The ReadFile done by referrers does,
		// but the loader's cgo preprocessing currently does not.

		if len(modified) > 0 {
			ctxt = buildutil.OverlayContext(ctxt, modified)
		}
	}

	var outputMu sync.Mutex
	output := func(fset *token.FileSet, qr QueryResult) {
		outputMu.Lock()
		defer outputMu.Unlock()
		if *jsonFlag {
			// JSON output
			fmt.Printf("%s\n", qr.JSON(fset))
		} else {
			// plain output
			printf := func(pos interface{}, format string, args ...interface{}) {
				fprintf(os.Stdout, fset, pos, format, args...)
			}
			qr.PrintPlain(printf)
		}
	}

	// Avoid corner case of split("").
	var scope []string
	if *scopeFlag != "" {
		scope = strings.Split(*scopeFlag, ",")
	}

	// Ask the guru.
	query := Query{
		Pos:        posn,
		Build:      ctxt,
		Scope:      scope,
		PTALog:     ptalog,
		Reflection: *reflectFlag,
		Output:     output,
	}

	if err := Run(mode, &query); err != nil {
		log.Fatal(err)
	}
}
