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

// The eg command performs example-based refactoring.
// For documentation, run the command, or see Help in
// golang.org/x/tools/refactor/eg.
package main // import "golang.org/x/tools/cmd/eg"

import (
	"flag"
	"fmt"
	"go/build"
	"go/format"
	"go/parser"
	"go/token"
	exec "golang.org/x/sys/execabs"
	"os"
	"strings"

	"golang.org/x/tools/go/buildutil"
	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/refactor/eg"
)

var (
	beforeeditFlag = flag.String("beforeedit", "", "A command to exec before each file is edited (e.g. chmod, checkout).  Whitespace delimits argument words.  The string '{}' is replaced by the file name.")
	helpFlag       = flag.Bool("help", false, "show detailed help message")
	templateFlag   = flag.String("t", "", "template.go file specifying the refactoring")
	transitiveFlag = flag.Bool("transitive", false, "apply refactoring to all dependencies too")
	writeFlag      = flag.Bool("w", false, "rewrite input files in place (by default, the results are printed to standard output)")
	verboseFlag    = flag.Bool("v", false, "show verbose matcher diagnostics")
)

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

const usage = `eg: an example-based refactoring tool.

Usage: eg -t template.go [-w] [-transitive] <args>...

-help            show detailed help message
-t template.go	 specifies the template file (use -help to see explanation)
-w          	 causes files to be re-written in place.
-transitive 	 causes all dependencies to be refactored too.
-v               show verbose matcher diagnostics
-beforeedit cmd  a command to exec before each file is modified.
                 "{}" represents the name of the file.
` + loader.FromArgsUsage

func main() {
	if err := doMain(); err != nil {
		fmt.Fprintf(os.Stderr, "eg: %s\n", err)
		os.Exit(1)
	}
}

func doMain() error {
	flag.Parse()
	args := flag.Args()

	if *helpFlag {
		fmt.Fprint(os.Stderr, eg.Help)
		os.Exit(2)
	}

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

	if *templateFlag == "" {
		return fmt.Errorf("no -t template.go file specified")
	}

	conf := loader.Config{
		Fset:       token.NewFileSet(),
		ParserMode: parser.ParseComments,
	}

	// The first Created package is the template.
	conf.CreateFromFilenames("template", *templateFlag)

	if _, err := conf.FromArgs(args, true); err != nil {
		return err
	}

	// Load, parse and type-check the whole program.
	iprog, err := conf.Load()
	if err != nil {
		return err
	}

	// Analyze the template.
	template := iprog.Created[0]
	xform, err := eg.NewTransformer(iprog.Fset, template.Pkg, template.Files[0], &template.Info, *verboseFlag)
	if err != nil {
		return err
	}

	// Apply it to the input packages.
	var pkgs []*loader.PackageInfo
	if *transitiveFlag {
		for _, info := range iprog.AllPackages {
			pkgs = append(pkgs, info)
		}
	} else {
		pkgs = iprog.InitialPackages()
	}
	var hadErrors bool
	for _, pkg := range pkgs {
		if pkg == template {
			continue
		}
		for _, file := range pkg.Files {
			n := xform.Transform(&pkg.Info, pkg.Pkg, file)
			if n == 0 {
				continue
			}
			filename := iprog.Fset.File(file.Pos()).Name()
			fmt.Fprintf(os.Stderr, "=== %s (%d matches)\n", filename, n)
			if *writeFlag {
				// Run the before-edit command (e.g. "chmod +w",  "checkout") if any.
				if *beforeeditFlag != "" {
					args := strings.Fields(*beforeeditFlag)
					// Replace "{}" with the filename, like find(1).
					for i := range args {
						if i > 0 {
							args[i] = strings.Replace(args[i], "{}", filename, -1)
						}
					}
					cmd := exec.Command(args[0], args[1:]...)
					cmd.Stdout = os.Stdout
					cmd.Stderr = os.Stderr
					if err := cmd.Run(); err != nil {
						fmt.Fprintf(os.Stderr, "Warning: edit hook %q failed (%s)\n",
							args, err)
					}
				}
				if err := eg.WriteAST(iprog.Fset, filename, file); err != nil {
					fmt.Fprintf(os.Stderr, "eg: %s\n", err)
					hadErrors = true
				}
			} else {
				format.Node(os.Stdout, iprog.Fset, file)
			}
		}
	}
	if hadErrors {
		os.Exit(1)
	}
	return nil
}
