// 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 (
	"flag"
	"fmt"
	"go/build"
	"go/token"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"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)

	// gccgo does not provide a GOROOT with standard library sources.
	// If we have one in the environment, force gc mode.
	if build.Default.Compiler == "gccgo" {
		if _, err := os.Stat(filepath.Join(runtime.GOROOT(), "src", "runtime", "runtime.go")); err == nil {
			build.Default.Compiler = "gc"
		}
	}
}

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
	referrers 	show all refs to entity denoted by selected identifier
	what		show basic information about the selected syntax node

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.Fprint(os.Stderr, helpMessage)
	fmt.Fprintln(os.Stderr, "\nFlags:")
	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)
	}

	// 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)
		}
	}

	// Ask the guru.
	query := Query{
		Pos:    posn,
		Build:  ctxt,
		Output: output,
	}

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