// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// licence that can be found in the LICENSE file.

// This file contains the implementation of the 'gomvpkg' command
// whose main function is in golang.org/x/tools/cmd/gomvpkg.

package rename

// TODO(matloob):
// - think about what happens if the package is moving across version control systems.
// - think about windows, which uses "\" as its directory separator.
// - dot imports are not supported. Make sure it's clearly documented.

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/build"
	"go/format"
	"go/token"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"text/template"

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

// Move, given a package path and a destination package path, will try
// to move the given package to the new path. The Move function will
// first check for any conflicts preventing the move, such as a
// package already existing at the destination package path. If the
// move can proceed, it builds an import graph to find all imports of
// the packages whose paths need to be renamed. This includes uses of
// the subpackages of the package to be moved as those packages will
// also need to be moved. It then renames all imports to point to the
// new paths, and then moves the packages to their new paths.
func Move(ctxt *build.Context, from, to, moveTmpl string) error {
	srcDir, err := srcDir(ctxt, from)
	if err != nil {
		return err
	}

	// This should be the only place in the program that constructs
	// file paths.
	// TODO(matloob): test on Microsoft Windows.
	fromDir := buildutil.JoinPath(ctxt, srcDir, filepath.FromSlash(from))
	toDir := buildutil.JoinPath(ctxt, srcDir, filepath.FromSlash(to))
	toParent := filepath.Dir(toDir)
	if !buildutil.IsDir(ctxt, toParent) {
		return fmt.Errorf("parent directory does not exist for path %s", toDir)
	}

	// Build the import graph and figure out which packages to update.
	_, rev, errors := importgraph.Build(ctxt)
	if len(errors) > 0 {
		// With a large GOPATH tree, errors are inevitable.
		// Report them but proceed.
		fmt.Fprintf(os.Stderr, "While scanning Go workspace:\n")
		for path, err := range errors {
			fmt.Fprintf(os.Stderr, "Package %q: %s.\n", path, err)
		}
	}

	// Determine the affected packages---the set of packages whose import
	// statements need updating.
	affectedPackages := map[string]bool{from: true}
	destinations := make(map[string]string) // maps old import path to new import path
	for pkg := range subpackages(ctxt, srcDir, from) {
		for r := range rev[pkg] {
			affectedPackages[r] = true
		}
		// Ensure directories have a trailing separator.
		dest := strings.Replace(pkg,
			filepath.Join(from, ""),
			filepath.Join(to, ""),
			1)
		destinations[pkg] = filepath.ToSlash(dest)
	}

	// Load all the affected packages.
	iprog, err := loadProgram(ctxt, affectedPackages)
	if err != nil {
		return err
	}

	// Prepare the move command, if one was supplied.
	var cmd string
	if moveTmpl != "" {
		if cmd, err = moveCmd(moveTmpl, fromDir, toDir); err != nil {
			return err
		}
	}

	m := mover{
		ctxt:             ctxt,
		rev:              rev,
		iprog:            iprog,
		from:             from,
		to:               to,
		fromDir:          fromDir,
		toDir:            toDir,
		affectedPackages: affectedPackages,
		destinations:     destinations,
		cmd:              cmd,
	}

	if err := m.checkValid(); err != nil {
		return err
	}

	m.move()

	return nil
}

// srcDir returns the absolute path of the srcdir containing pkg.
func srcDir(ctxt *build.Context, pkg string) (string, error) {
	for _, srcDir := range ctxt.SrcDirs() {
		path := buildutil.JoinPath(ctxt, srcDir, pkg)
		if buildutil.IsDir(ctxt, path) {
			return srcDir, nil
		}
	}
	return "", fmt.Errorf("src dir not found for package: %s", pkg)
}

// subpackages returns the set of packages in the given srcDir whose
// import paths start with dir.
func subpackages(ctxt *build.Context, srcDir string, dir string) map[string]bool {
	subs := map[string]bool{dir: true}

	// Find all packages under srcDir whose import paths start with dir.
	buildutil.ForEachPackage(ctxt, func(pkg string, err error) {
		if err != nil {
			log.Fatalf("unexpected error in ForEachPackage: %v", err)
		}

		if !strings.HasPrefix(pkg, path.Join(dir, "")) {
			return
		}

		p, err := ctxt.Import(pkg, "", build.FindOnly)
		if err != nil {
			log.Fatalf("unexpected: package %s can not be located by build context: %s", pkg, err)
		}
		if p.SrcRoot == "" {
			log.Fatalf("unexpected: could not determine srcDir for package %s: %s", pkg, err)
		}
		if p.SrcRoot != srcDir {
			return
		}

		subs[pkg] = true
	})

	return subs
}

type mover struct {
	// iprog contains all packages whose contents need to be updated
	// with new package names or import paths.
	iprog *loader.Program
	ctxt  *build.Context
	// rev is the reverse import graph.
	rev importgraph.Graph
	// from and to are the source and destination import
	// paths. fromDir and toDir are the source and destination
	// absolute paths that package source files will be moved between.
	from, to, fromDir, toDir string
	// affectedPackages is the set of all packages whose contents need
	// to be updated to reflect new package names or import paths.
	affectedPackages map[string]bool
	// destinations maps each subpackage to be moved to its
	// destination path.
	destinations map[string]string
	// cmd, if not empty, will be executed to move fromDir to toDir.
	cmd string
}

func (m *mover) checkValid() error {
	const prefix = "invalid move destination"

	match, err := regexp.MatchString("^[_\\pL][_\\pL\\p{Nd}]*$", path.Base(m.to))
	if err != nil {
		panic("regexp.MatchString failed")
	}
	if !match {
		return fmt.Errorf("%s: %s; gomvpkg does not support move destinations "+
			"whose base names are not valid go identifiers", prefix, m.to)
	}

	if buildutil.FileExists(m.ctxt, m.toDir) {
		return fmt.Errorf("%s: %s conflicts with file %s", prefix, m.to, m.toDir)
	}
	if buildutil.IsDir(m.ctxt, m.toDir) {
		return fmt.Errorf("%s: %s conflicts with directory %s", prefix, m.to, m.toDir)
	}

	for _, toSubPkg := range m.destinations {
		if _, err := m.ctxt.Import(toSubPkg, "", build.FindOnly); err == nil {
			return fmt.Errorf("%s: %s; package or subpackage %s already exists",
				prefix, m.to, toSubPkg)
		}
	}

	return nil
}

// moveCmd produces the version control move command used to move fromDir to toDir by
// executing the given template.
func moveCmd(moveTmpl, fromDir, toDir string) (string, error) {
	tmpl, err := template.New("movecmd").Parse(moveTmpl)
	if err != nil {
		return "", err
	}

	var buf bytes.Buffer
	err = tmpl.Execute(&buf, struct {
		Src string
		Dst string
	}{fromDir, toDir})
	return buf.String(), err
}

func (m *mover) move() error {
	filesToUpdate := make(map[*ast.File]bool)

	// Change the moved package's "package" declaration to its new base name.
	pkg, ok := m.iprog.Imported[m.from]
	if !ok {
		log.Fatalf("unexpected: package %s is not in import map", m.from)
	}
	newName := filepath.Base(m.to)
	for _, f := range pkg.Files {
		// Update all import comments.
		for _, cg := range f.Comments {
			c := cg.List[0]
			if c.Slash >= f.Name.End() &&
				sameLine(m.iprog.Fset, c.Slash, f.Name.End()) &&
				(f.Decls == nil || c.Slash < f.Decls[0].Pos()) {
				if strings.HasPrefix(c.Text, `// import "`) {
					c.Text = `// import "` + m.to + `"`
					break
				}
				if strings.HasPrefix(c.Text, `/* import "`) {
					c.Text = `/* import "` + m.to + `" */`
					break
				}
			}
		}
		f.Name.Name = newName // change package decl
		filesToUpdate[f] = true
	}

	// Look through the external test packages (m.iprog.Created contains the external test packages).
	for _, info := range m.iprog.Created {
		// Change the "package" declaration of the external test package.
		if info.Pkg.Path() == m.from+"_test" {
			for _, f := range info.Files {
				f.Name.Name = newName + "_test" // change package decl
				filesToUpdate[f] = true
			}
		}

		// Mark all the loaded external test packages, which import the "from" package,
		// as affected packages and update the imports.
		for _, imp := range info.Pkg.Imports() {
			if imp.Path() == m.from {
				m.affectedPackages[info.Pkg.Path()] = true
				m.iprog.Imported[info.Pkg.Path()] = info
				if err := importName(m.iprog, info, m.from, path.Base(m.from), newName); err != nil {
					return err
				}
			}
		}
	}

	// Update imports of that package to use the new import name.
	// None of the subpackages will change their name---only the from package
	// itself will.
	for p := range m.rev[m.from] {
		if err := importName(m.iprog, m.iprog.Imported[p], m.from, path.Base(m.from), newName); err != nil {
			return err
		}
	}

	// Update import paths for all imports by affected packages.
	for ap := range m.affectedPackages {
		info, ok := m.iprog.Imported[ap]
		if !ok {
			log.Fatalf("unexpected: package %s is not in import map", ap)
		}
		for _, f := range info.Files {
			for _, imp := range f.Imports {
				importPath, _ := strconv.Unquote(imp.Path.Value)
				if newPath, ok := m.destinations[importPath]; ok {
					imp.Path.Value = strconv.Quote(newPath)

					oldName := path.Base(importPath)
					if imp.Name != nil {
						oldName = imp.Name.Name
					}

					newName := path.Base(newPath)
					if imp.Name == nil && oldName != newName {
						imp.Name = ast.NewIdent(oldName)
					} else if imp.Name == nil || imp.Name.Name == newName {
						imp.Name = nil
					}
					filesToUpdate[f] = true
				}
			}
		}
	}

	for f := range filesToUpdate {
		var buf bytes.Buffer
		if err := format.Node(&buf, m.iprog.Fset, f); err != nil {
			log.Printf("failed to pretty-print syntax tree: %v", err)
			continue
		}
		tokenFile := m.iprog.Fset.File(f.Pos())
		writeFile(tokenFile.Name(), buf.Bytes())
	}

	// Move the directories.
	// If either the fromDir or toDir are contained under version control it is
	// the user's responsibility to provide a custom move command that updates
	// version control to reflect the move.
	// TODO(matloob): If the parent directory of toDir does not exist, create it.
	//      For now, it's required that it does exist.

	if m.cmd != "" {
		// TODO(matloob): Verify that the windows and plan9 cases are correct.
		var cmd *exec.Cmd
		switch runtime.GOOS {
		case "windows":
			cmd = exec.Command("cmd", "/c", m.cmd)
		case "plan9":
			cmd = exec.Command("rc", "-c", m.cmd)
		default:
			cmd = exec.Command("sh", "-c", m.cmd)
		}
		cmd.Stderr = os.Stderr
		cmd.Stdout = os.Stdout
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("version control system's move command failed: %v", err)
		}

		return nil
	}

	return moveDirectory(m.fromDir, m.toDir)
}

// sameLine reports whether two positions in the same file are on the same line.
func sameLine(fset *token.FileSet, x, y token.Pos) bool {
	return fset.Position(x).Line == fset.Position(y).Line
}

var moveDirectory = func(from, to string) error {
	return os.Rename(from, to)
}
