// Package strip removes Godeps/_workspace and undoes the Godep rewrites. This
// essentially removes the old style (pre-vendor) Godep vendoring.
//
// Note, this functionality is deprecated. Once more projects use the Godep
// support for the core vendoring this will no longer be needed.
package strip

import (
	"bytes"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/Masterminds/glide/msg"
)

var godepMark = map[string]bool{}

var vPath = "vendor"

// GodepWorkspace removes any Godeps/_workspace directories and makes sure
// any rewrites are undone.
// Note, this is not concuccency safe.
func GodepWorkspace(v string) error {
	vPath = v
	if _, err := os.Stat(vPath); err != nil {
		if os.IsNotExist(err) {
			msg.Debug("Vendor directory does not exist.")
		}

		return err
	}

	err := filepath.Walk(vPath, stripGodepWorkspaceHandler)
	if err != nil {
		return err
	}

	// Walk the marked projects to make sure rewrites are undone.
	for k := range godepMark {
		msg.Info("Removing Godep rewrites for %s", k)
		err := filepath.Walk(k, rewriteGodepfilesHandler)
		if err != nil {
			return err
		}
	}

	return nil
}

func stripGodepWorkspaceHandler(path string, info os.FileInfo, err error) error {
	// Skip the base vendor directory
	if path == vPath {
		return nil
	}

	name := info.Name()
	p := filepath.Dir(path)
	pn := filepath.Base(p)
	if name == "_workspace" && pn == "Godeps" {
		if _, err := os.Stat(path); err == nil {
			if info.IsDir() {
				// Marking this location to make sure rewrites are undone.
				pp := filepath.Dir(p)
				godepMark[pp] = true

				msg.Info("Removing: %s", path)
				return os.RemoveAll(path)
			}

			msg.Debug("%s is not a directory. Skipping removal", path)
			return nil
		}
	}
	return nil
}

func rewriteGodepfilesHandler(path string, info os.FileInfo, err error) error {
	name := info.Name()

	if info.IsDir() {
		if name == "testdata" || name == "vendor" {
			return filepath.SkipDir
		}
		return nil
	}

	if e := filepath.Ext(path); e != ".go" {
		return nil
	}

	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
	if err != nil {
		return err
	}

	var changed bool
	for _, s := range f.Imports {
		n, err := strconv.Unquote(s.Path.Value)
		if err != nil {
			return err
		}
		q := rewriteGodepImport(n)
		if q != name {
			s.Path.Value = strconv.Quote(q)
			changed = true
		}
	}
	if !changed {
		return nil
	}

	printerConfig := &printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}
	var buffer bytes.Buffer
	if err = printerConfig.Fprint(&buffer, fset, f); err != nil {
		return err
	}
	fset = token.NewFileSet()
	f, err = parser.ParseFile(fset, name, &buffer, parser.ParseComments)
	ast.SortImports(fset, f)
	tpath := path + ".temp"
	t, err := os.Create(tpath)
	if err != nil {
		return err
	}
	if err = printerConfig.Fprint(t, fset, f); err != nil {
		return err
	}
	if err = t.Close(); err != nil {
		return err
	}

	msg.Debug("Rewriting Godep imports for %s", path)

	// This is required before the rename on windows.
	if err = os.Remove(path); err != nil {
		return err
	}
	return os.Rename(tpath, path)
}

func rewriteGodepImport(n string) string {
	if !strings.Contains(n, "Godeps/_workspace/src") {
		return n
	}

	i := strings.LastIndex(n, "Godeps/_workspace/src")

	return strings.TrimPrefix(n[i:], "Godeps/_workspace/src/")
}
