package action

import (
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"sync"

	"github.com/Masterminds/glide/cache"
	"github.com/Masterminds/glide/cfg"
	"github.com/Masterminds/glide/dependency"
	"github.com/Masterminds/glide/gb"
	"github.com/Masterminds/glide/godep"
	"github.com/Masterminds/glide/gom"
	"github.com/Masterminds/glide/gpm"
	"github.com/Masterminds/glide/msg"
	gpath "github.com/Masterminds/glide/path"
	"github.com/Masterminds/glide/util"
	"github.com/Masterminds/semver"
	"github.com/Masterminds/vcs"
)

// TODO(mattfarina): This file could really use to be cleaned up. It's functional
// but not all that elegant. This mess of code really needs someone to come
// along and clean it up. Pretty please.

// Create creates/initializes a new Glide repository.
//
// This will fail if a glide.yaml already exists.
//
// By default, this will scan the present source code directory for dependencies.
//
// If skipImport is set to true, this will not attempt to import from an existing
// GPM, Godep, or GB project if one should exist. However, it will still attempt
// to read the local source to determine required packages.
func Create(base string, skipImport, noInteract, skipVerSug bool) {
	glidefile := gpath.GlideFile
	// Guard against overwrites.
	guardYAML(glidefile)

	// Guess deps
	conf := guessDeps(base, skipImport, noInteract, skipVerSug)
	// Write YAML
	msg.Info("Writing glide.yaml file")
	if err := conf.WriteFile(glidefile); err != nil {
		msg.Die("Could not save %s: %s", glidefile, err)
	}
	msg.Info("You can now edit the glide.yaml file. Consider:")
	msg.Info("--> Using versions and ranges. See https://glide.sh/docs/versions/")
	msg.Info("--> Adding additional metadata. See https://glide.sh/docs/glide.yaml/")
}

// guardYAML fails if the given file already exists.
//
// This prevents an important file from being overwritten.
func guardYAML(filename string) {
	if _, err := os.Stat(filename); err == nil {
		msg.Die("Cowardly refusing to overwrite existing YAML.")
	}
}

// guessDeps attempts to resolve all of the dependencies for a given project.
//
// base is the directory to start with.
// skipImport will skip running the automatic imports.
//
// FIXME: This function is likely a one-off that has a more standard alternative.
// It's also long and could use a refactor.
func guessDeps(base string, skipImport, noInteract, skipVerSug bool) *cfg.Config {
	buildContext, err := util.GetBuildContext()
	if err != nil {
		msg.Die("Failed to build an import context: %s", err)
	}
	name := buildContext.PackageName(base)

	msg.Info("Generating a YAML configuration file and guessing the dependencies")

	config := new(cfg.Config)

	// Get the name of the top level package
	config.Name = name

	// Import by looking at other package managers and looking over the
	// entire directory structure.
	var deps cfg.Dependencies

	// Attempt to import from other package managers.
	if !skipImport {
		deps = guessImportDeps(base)
		if len(deps) == 0 {
			msg.Info("No dependencies found to import")
		}
	}

	msg.Info("Scanning code to look for dependencies")

	// Resolve dependencies by looking at the tree.
	r, err := dependency.NewResolver(base)
	if err != nil {
		msg.Die("Error creating a dependency resolver: %s", err)
	}

	h := &dependency.DefaultMissingPackageHandler{Missing: []string{}, Gopath: []string{}}
	r.Handler = h

	sortable, err := r.ResolveLocal(false)
	if err != nil {
		msg.Die("Error resolving local dependencies: %s", err)
	}

	sort.Strings(sortable)

	vpath := r.VendorDir
	if !strings.HasSuffix(vpath, "/") {
		vpath = vpath + string(os.PathSeparator)
	}

	var count int
	var all string
	var allOnce bool
	for _, pa := range sortable {
		n := strings.TrimPrefix(pa, vpath)
		root, subpkg := util.NormalizeName(n)

		if !config.HasDependency(root) && root != config.Name {
			count++
			d := deps.Get(root)
			if d == nil {
				d = &cfg.Dependency{
					Name: root,
				}
				msg.Info("--> Found reference to %s", n)
			} else {
				msg.Info("--> Found imported reference to %s", n)
			}

			all, allOnce = guessAskVersion(noInteract, all, allOnce, skipVerSug, d)

			if subpkg != "" {
				if !d.HasSubpackage(subpkg) {
					d.Subpackages = append(d.Subpackages, subpkg)
				}
				msg.Verbose("--> Noting sub-package %s to %s", subpkg, root)
			}

			config.Imports = append(config.Imports, d)
		} else if config.HasDependency(root) {
			if len(subpkg) > 0 {
				subpkg = strings.TrimPrefix(subpkg, "/")
				d := config.Imports.Get(root)
				if !d.HasSubpackage(subpkg) {
					d.Subpackages = append(d.Subpackages, subpkg)
				}
				msg.Verbose("--> Noting sub-package %s to %s", subpkg, root)
			}
		}
	}

	if !skipImport && len(deps) > count {
		var res string
		if noInteract {
			res = "y"
		} else {
			msg.Info("%d unused imported dependencies found. These are likely transitive dependencies ", len(deps)-count)
			msg.Info("(dependencies of your dependencies). Would you like to track them in your")
			msg.Info("glide.yaml file? Note, Glide will automatically scan your codebase to detect")
			msg.Info("the complete dependency tree and import the complete tree. If your dependencies")
			msg.Info("do not track dependency version information some version information may be lost.")
			msg.Info("Yes (Y) or No (N)?")
			res, err = msg.PromptUntil([]string{"y", "yes", "n", "no"})
			if err != nil {
				msg.Die("Error processing response: %s", err)
			}
		}
		if res == "y" || res == "yes" {
			msg.Info("Including additional imports in the glide.yaml file")
			for _, dep := range deps {
				found := config.Imports.Get(dep.Name)
				if found == nil {
					config.Imports = append(config.Imports, dep)
					if dep.Reference != "" {
						all, allOnce = guessAskVersion(noInteract, all, allOnce, skipVerSug, dep)
						msg.Info("--> Adding %s at version %s", dep.Name, dep.Reference)
					} else {
						msg.Info("--> Adding %s", dep.Name)
					}
				}
			}
		}
	}

	return config
}

func guessAskVersion(noInteract bool, all string, allonce, skipVerSug bool, d *cfg.Dependency) (string, bool) {
	if !noInteract && !skipVerSug && d.Reference == "" {
		// If scanning has not happened already, for example this isn't an
		// import, try it now.
		var loc string
		if d.Repository != "" {
			loc = d.Repository
		} else {
			loc = "https://" + d.Name
		}
		if !guessVersionCache.checked(loc) {
			createGuessVersion(loc, d.Reference)
		}

		semv := guessVersionCache.get(loc)
		if semv != "" {
			msg.Info("The package %s appears to have Semantic Version releases. The latest", d.Name)
			msg.Info("release is %s. Would you like to use this release? Yes (Y) or No (N)", semv)
			res, err2 := msg.PromptUntil([]string{"y", "yes", "n", "no"})
			if err2 != nil {
				msg.Die("Error processing response: %s", err2)
			}

			if res == "y" || res == "yes" {
				d.Reference = semv
			}
		}

	}

	if !noInteract && d.Reference != "" {
		var changedVer bool
		ver, err := semver.NewVersion(d.Reference)
		if err != nil && !skipVerSug {
			var loc string
			if d.Repository != "" {
				loc = d.Repository
			} else {
				loc = "https://" + d.Name
			}

			semv := guessVersionCache.get(loc)
			if semv != "" {
				msg.Info("The package %s appears to have Semantic Version releases but the imported data", d.Name)
				msg.Info("is not using them. The latest release is %s but the imported data is using %s.", semv, d.Reference)
				msg.Info("Would you like to use the latest release version instead? Yes (Y) or No (N)")
				res, err2 := msg.PromptUntil([]string{"y", "yes", "n", "no"})
				if err2 != nil {
					msg.Die("Error processing response: %s", err2)
				}

				if res == "y" || res == "yes" {
					d.Reference = semv
					changedVer = true
				}
			}
		}

		if changedVer {
			ver, err = semver.NewVersion(d.Reference)
		}
		if err == nil {
			if all == "" {
				vstr := ver.String()
				msg.Info("Imported dependency %s (%s) appears to use semantic versions (http://semver.org).", d.Name, d.Reference)
				msg.Info("Would you like Glide to track the latest minor or patch releases (major.minor.path)?")
				msg.Info("Tracking minor version releases would use '>= %s, < %d.0.0' ('^%s'). Tracking patch version", vstr, ver.Major()+1, vstr)
				msg.Info("releases would use '>= %s, < %d.%d.0' ('~%s'). For more information on Glide versions", vstr, ver.Major(), ver.Minor()+1, vstr)
				msg.Info("and ranges see https://glide.sh/docs/versions")
				msg.Info("Minor (M), Patch (P), or Skip Ranges (S)?")
				res, err := msg.PromptUntil([]string{"minor", "m", "patch", "p", "skip ranges", "s"})
				if err != nil {
					msg.Die("Error processing response: %s", err)
				}
				if res == "m" || res == "minor" {
					d.Reference = "^" + vstr
				} else if res == "p" || res == "patch" {
					d.Reference = "~" + vstr
				}

				if !allonce {
					msg.Info("Would you like to same response (%s) for future dependencies? Yes (Y) or No (N)", res)
					res2, err := msg.PromptUntil([]string{"y", "yes", "n", "no"})
					if err != nil {
						msg.Die("Error processing response: %s", err)
					}
					if res2 == "yes" || res2 == "y" {
						return res, true
					}

					return "", true
				}

			} else {
				if all == "m" || all == "minor" {
					d.Reference = "^" + ver.String()
				} else if all == "p" || all == "patch" {
					d.Reference = "~" + ver.String()
				}
			}

			return all, allonce
		}

		return all, allonce
	}

	return all, allonce
}

func guessImportDeps(base string) cfg.Dependencies {
	msg.Info("Attempting to import from other package managers (use --skip-import to skip)")
	deps := []*cfg.Dependency{}
	absBase, err := filepath.Abs(base)
	if err != nil {
		msg.Die("Failed to resolve location of %s: %s", base, err)
	}

	if d, ok := guessImportGodep(absBase); ok {
		msg.Info("Importing Godep configuration")
		msg.Warn("--> Godep uses commit id versions. Consider using Semantic Versions with Glide")
		deps = d
	} else if d, ok := guessImportGPM(absBase); ok {
		msg.Info("Importing GPM configuration")
		deps = d
	} else if d, ok := guessImportGB(absBase); ok {
		msg.Info("Importing GB configuration")
		deps = d
	} else if d, ok := guessImportGom(absBase); ok {
		msg.Info("Importing GB configuration")
		deps = d
	}

	if len(deps) > 0 {
		msg.Info("--> Attempting to detect versions from imported commit ids")
	}

	var wg sync.WaitGroup

	for _, i := range deps {
		wg.Add(1)
		go func(dep *cfg.Dependency) {
			var remote string
			if dep.Repository != "" {
				remote = dep.Repository
			} else {
				remote = "https://" + dep.Name
			}
			ver := createGuessVersion(remote, dep.Reference)
			if ver != dep.Reference {
				msg.Verbose("--> Found imported reference to %s at version %s", dep.Name, ver)
				dep.Reference = ver
			}

			msg.Debug("--> Found imported reference to %s at revision %s", dep.Name, dep.Reference)

			wg.Done()
		}(i)
	}

	wg.Wait()

	return deps
}

func guessImportGodep(dir string) ([]*cfg.Dependency, bool) {
	d, err := godep.Parse(dir)
	if err != nil || len(d) == 0 {
		return []*cfg.Dependency{}, false
	}

	return d, true
}

func guessImportGPM(dir string) ([]*cfg.Dependency, bool) {
	d, err := gpm.Parse(dir)
	if err != nil || len(d) == 0 {
		return []*cfg.Dependency{}, false
	}

	return d, true
}

func guessImportGB(dir string) ([]*cfg.Dependency, bool) {
	d, err := gb.Parse(dir)
	if err != nil || len(d) == 0 {
		return []*cfg.Dependency{}, false
	}

	return d, true
}

func guessImportGom(dir string) ([]*cfg.Dependency, bool) {
	d, err := gom.Parse(dir)
	if err != nil || len(d) == 0 {
		return []*cfg.Dependency{}, false
	}

	return d, true
}

// Note, this really needs a simpler name.
var createGitParseVersion = regexp.MustCompile(`(?m-s)(?:tags)/(\S+)$`)

var guessVersionCache = newVersionCache()

func createGuessVersion(remote, id string) string {
	err := cache.Setup()
	if err != nil {
		msg.Debug("Problem setting up cache: %s", err)
	}
	l, err := cache.Location()
	if err != nil {
		msg.Debug("Problem detecting cache location: %s", err)
	}
	key, err := cache.Key(remote)
	if err != nil {
		msg.Debug("Problem generating cache key for %s: %s", remote, err)
	}

	local := filepath.Join(l, "src", key)
	repo, err := vcs.NewRepo(remote, local)
	if err != nil {
		msg.Debug("Problem getting repo instance: %s", err)
	}

	// Git endpoints allow for querying without fetching the codebase locally.
	// We try that first to avoid fetching right away. Is this premature
	// optimization?
	cc := true
	if repo.Vcs() == vcs.Git {
		out, err := exec.Command("git", "ls-remote", remote).CombinedOutput()
		if err == nil {
			guessVersionCache.touchChecked(remote)
			cc = false
			lines := strings.Split(string(out), "\n")
			res := ""

			// TODO(mattfarina): Detect if the found version is semver and use
			// that one instead of the first found.
			for _, i := range lines {
				ti := strings.TrimSpace(i)
				if found := createGitParseVersion.FindString(ti); found != "" {
					tg := strings.TrimPrefix(strings.TrimSuffix(found, "^{}"), "tags/")
					if strings.HasPrefix(ti, id) {
						res = tg
					}

					ver, err := semver.NewVersion(tg)
					if err == nil {
						if guessVersionCache.get(remote) == "" {
							guessVersionCache.put(remote, tg)
						} else {
							ver2, err := semver.NewVersion(guessVersionCache.get(remote))
							if err == nil {
								if ver.GreaterThan(ver2) {
									guessVersionCache.put(remote, tg)
								}
							}
						}
					}
				}
			}

			if res != "" {
				return res
			}
		}
	}

	if cc {
		cache.Lock(key)
		if _, err = os.Stat(local); os.IsNotExist(err) {
			repo.Get()
			branch := findCurrentBranch(repo)
			c := cache.RepoInfo{DefaultBranch: branch}
			err = cache.SaveRepoData(key, c)
			if err != nil {
				msg.Debug("Error saving cache repo details: %s", err)
			}
		} else {
			repo.Update()
		}

		tgs, err := repo.TagsFromCommit(id)
		if err != nil {
			msg.Debug("Problem getting tags for commit: %s", err)
		}
		cache.Unlock(key)
		if len(tgs) > 0 {
			return tgs[0]
		}
	}

	return id
}

func findCurrentBranch(repo vcs.Repo) string {
	msg.Debug("Attempting to find current branch for %s", repo.Remote())
	// Svn and Bzr don't have default branches.
	if repo.Vcs() == vcs.Svn || repo.Vcs() == vcs.Bzr {
		return ""
	}

	if repo.Vcs() == vcs.Git || repo.Vcs() == vcs.Hg {
		ver, err := repo.Current()
		if err != nil {
			msg.Debug("Unable to find current branch for %s, error: %s", repo.Remote(), err)
			return ""
		}
		return ver
	}

	return ""
}

type versionCache struct {
	sync.RWMutex
	cache map[string]string
	cd    map[string]bool
}

func newVersionCache() *versionCache {
	return &versionCache{
		cache: make(map[string]string),
		cd:    make(map[string]bool),
	}
}

func (v *versionCache) put(name, version string) {
	v.Lock()
	defer v.Unlock()
	v.cache[name] = version
	v.cd[name] = true
}

func (v *versionCache) checked(name string) bool {
	v.RLock()
	defer v.RUnlock()
	return v.cd[name]
}

func (v *versionCache) touchChecked(name string) {
	v.Lock()
	defer v.Unlock()
	v.cd[name] = true
}

func (v *versionCache) get(name string) string {
	v.RLock()
	defer v.RUnlock()
	return v.cache[name]
}
