// +build ignore

package main

// ssadump: a tool for displaying and interpreting the SSA form of Go programs.

import (
	"flag"
	"fmt"
	"go/ast"
	"log"
	"os"
	"runtime/pprof"
	"strings"

	"code.google.com/p/go.exp/ssa"
	"code.google.com/p/go.exp/ssa/interp"
)

// TODO(adonovan): perhaps these should each be separate flags?
var buildFlag = flag.String("build", "", `Options controlling the SSA builder.
The value is a sequence of zero or more of these letters:
C	perform sanity [C]hecking of the SSA form.
P	log [P]ackage inventory.
F	log [F]unction SSA code.
S	log [S]ource locations as SSA builder progresses.
G	use binary object files from gc to provide imports (no code).
L	build distinct packages seria[L]ly instead of in parallel.
N	build [N]aive SSA form: don't replace local loads/stores with registers.
`)

var runFlag = flag.Bool("run", false, "Invokes the SSA interpreter on the program.")

var interpFlag = flag.String("interp", "", `Options controlling the SSA test interpreter.
The value is a sequence of zero or more more of these letters:
R	disable [R]ecover() from panic; show interpreter crash instead.
T	[T]race execution of the program.  Best for single-threaded programs!
`)

const usage = `SSA builder and interpreter.
Usage: ssadump [<flag> ...] [<file.go> ...] [<arg> ...]
       ssadump [<flag> ...] <import/path>   [<arg> ...]
Use -help flag to display options.

Examples:
% ssadump -run -interp=T hello.go     # interpret a program, with tracing
% ssadump -build=FPG hello.go         # quickly dump SSA form of a single package
`

var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

func main() {
	flag.Parse()
	args := flag.Args()

	// TODO(adonovan): perhaps we need a more extensible option
	// API than a bitset, e.g. a struct with a sane zero value?
	var mode ssa.BuilderMode
	for _, c := range *buildFlag {
		switch c {
		case 'P':
			mode |= ssa.LogPackages | ssa.BuildSerially
		case 'F':
			mode |= ssa.LogFunctions | ssa.BuildSerially
		case 'S':
			mode |= ssa.LogSource | ssa.BuildSerially
		case 'C':
			mode |= ssa.SanityCheckFunctions
		case 'N':
			mode |= ssa.NaiveForm
		case 'G':
			mode |= ssa.UseGCImporter
		case 'L':
			mode |= ssa.BuildSerially
		default:
			log.Fatalf("Unknown -build option: '%c'.", c)
		}
	}

	var interpMode interp.Mode
	for _, c := range *interpFlag {
		switch c {
		case 'T':
			interpMode |= interp.EnableTracing
		case 'R':
			interpMode |= interp.DisableRecover
		default:
			log.Fatalf("Unknown -interp option: '%c'.", c)
		}
	}

	if len(args) == 0 {
		fmt.Fprint(os.Stderr, usage)
		os.Exit(1)
	}

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

	// TODO(adonovan/gri): the cascade of errors is confusing due
	// to reentrant control flow.  Disable for now and re-think.
	var errh func(error)
	// errh = func(err error) { fmt.Println(err.Error()) }

	loader := ssa.GorootLoader
	b := ssa.NewBuilder(mode, loader, errh)

	var pkgname string
	var files []*ast.File
	var err error

	switch {
	case len(args) == 0:
		log.Fatal("No *.go source files nor package name was specified.")

	case strings.HasSuffix(args[0], ".go"):
		// % ssadump a.go b.go ...
		// Leading consecutive *.go arguments constitute main package.
		i := 1
		for ; i < len(args) && strings.HasSuffix(args[i], ".go"); i++ {
		}
		files, err = ssa.ParseFiles(b.Prog.Files, ".", args[:i]...)
		pkgname = "main"
		args = args[i:]

	default:
		// % ssadump my/package ...
		// First argument is import path of main package.
		pkgname = args[0]
		args = args[1:]
		files, err = loader(b.Prog.Files, pkgname)
	}
	if err != nil {
		log.Fatalf(err.Error())
	}

	// TODO(gri): make it a typechecker error for there to be
	// duplicate (e.g.) main functions in the same package.
	mainpkg, err := b.CreatePackage(pkgname, files)
	if err != nil {
		log.Fatalf(err.Error())
	}
	b.BuildAllPackages()
	b = nil // discard Builder

	if *runFlag {
		interp.Interpret(mainpkg, interpMode, pkgname, args)
	}
}
