package action

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

	"github.com/Masterminds/glide/cache"
	"github.com/Masterminds/glide/cfg"
	"github.com/Masterminds/glide/msg"
	gpath "github.com/Masterminds/glide/path"
	"github.com/Masterminds/semver"
	"github.com/Masterminds/vcs"
)

// ConfigWizard reads configuration from a glide.yaml file and attempts to suggest
// improvements. The wizard is interactive.
func ConfigWizard(base string) {
	_, err := gpath.Glide()
	glidefile := gpath.GlideFile
	if err != nil {
		msg.Info("Unable to find a glide.yaml file. Would you like to create one now? Yes (Y) or No (N)")
		bres := msg.PromptUntilYorN()
		if bres {
			// Guess deps
			conf := guessDeps(base, false)
			// Write YAML
			if err := conf.WriteFile(glidefile); err != nil {
				msg.Die("Could not save %s: %s", glidefile, err)
			}
		} else {
			msg.Err("Unable to find configuration file. Please create configuration information to continue.")
		}
	}

	conf := EnsureConfig()

	err = cache.Setup()
	if err != nil {
		msg.Die("Problem setting up cache: %s", err)
	}

	msg.Info("Looking for dependencies to make suggestions on")
	msg.Info("--> Scanning for dependencies not using version ranges")
	msg.Info("--> Scanning for dependencies using commit ids")
	var deps []*cfg.Dependency
	for _, dep := range conf.Imports {
		if wizardLookInto(dep) {
			deps = append(deps, dep)
		}
	}
	for _, dep := range conf.DevImports {
		if wizardLookInto(dep) {
			deps = append(deps, dep)
		}
	}

	msg.Info("Gathering information on each dependency")
	msg.Info("--> This may take a moment. Especially on a codebase with many dependencies")
	msg.Info("--> Gathering release information for dependencies")
	msg.Info("--> Looking for dependency imports where versions are commit ids")
	for _, dep := range deps {
		wizardFindVersions(dep)
	}

	var changes int
	for _, dep := range deps {
		var remote string
		if dep.Repository != "" {
			remote = dep.Repository
		} else {
			remote = "https://" + dep.Name
		}

		// First check, ask if the tag should be used instead of the commit id for it.
		cur := cache.MemCurrent(remote)
		if cur != "" && cur != dep.Reference {
			wizardSugOnce()
			var dres bool
			asked, use, val := wizardOnce("current")
			if !use {
				dres = wizardAskCurrent(cur, dep)
			}
			if !asked {
				as := wizardRemember()
				wizardSetOnce("current", as, dres)
			}

			if asked && use {
				dres = val.(bool)
			}

			if dres {
				msg.Info("Updating %s to use the tag %s instead of commit id %s", dep.Name, cur, dep.Reference)
				dep.Reference = cur
				changes++
			}
		}

		// Second check, if no version is being used and there's a semver release ask about latest.
		memlatest := cache.MemLatest(remote)
		if dep.Reference == "" && memlatest != "" {
			wizardSugOnce()
			var dres bool
			asked, use, val := wizardOnce("latest")
			if !use {
				dres = wizardAskLatest(memlatest, dep)
			}
			if !asked {
				as := wizardRemember()
				wizardSetOnce("latest", as, dres)
			}

			if asked && use {
				dres = val.(bool)
			}

			if dres {
				msg.Info("Updating %s to use the release %s instead of no release", dep.Name, memlatest)
				dep.Reference = memlatest
				changes++
			}
		}

		// Third check, if the version is semver offer to use a range instead.
		sv, err := semver.NewVersion(dep.Reference)
		if err == nil {
			wizardSugOnce()
			var res string
			asked, use, val := wizardOnce("range")
			if !use {
				res = wizardAskRange(sv, dep)
			}
			if !asked {
				as := wizardRemember()
				wizardSetOnce("range", as, res)
			}

			if asked && use {
				res = val.(string)
			}

			if res == "m" {
				r := "^" + sv.String()
				msg.Info("Updating %s to use the range %s instead of commit id %s", dep.Name, r, dep.Reference)
				dep.Reference = r
				changes++
			} else if res == "p" {
				r := "~" + sv.String()
				msg.Info("Updating %s to use the range %s instead of commit id %s", dep.Name, r, dep.Reference)
				dep.Reference = r
				changes++
			}
		}
	}

	if changes > 0 {
		msg.Info("Configuration changes have been made. Would you like to write these")
		msg.Info("changes to your configuration file? Yes (Y) or No (N)")
		dres := msg.PromptUntilYorN()
		if dres {
			msg.Info("Writing updates to configuration file (%s)", glidefile)
			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.:")
			msg.Info("--> For more information on versions and ranges see https://glide.sh/docs/versions/")
			msg.Info("--> For details on additional metadata see https://glide.sh/docs/glide.yaml/")
		} else {
			msg.Warn("Change not written to configuration file")
		}
	} else {
		msg.Info("No proposed changes found. Have a nice day.")
	}
}

var wizardOnceVal = make(map[string]interface{})
var wizardOnceDo = make(map[string]bool)
var wizardOnceAsked = make(map[string]bool)

var wizardSuggeseOnce bool

func wizardSugOnce() {
	if !wizardSuggeseOnce {
		msg.Info("Here are some suggestions...")
	}
	wizardSuggeseOnce = true
}

// Returns if it's you should prompt, if not prompt if you should use stored value,
// and stored value if it has one.
func wizardOnce(name string) (bool, bool, interface{}) {
	return wizardOnceAsked[name], wizardOnceDo[name], wizardOnceVal[name]
}

func wizardSetOnce(name string, prompt bool, val interface{}) {
	wizardOnceAsked[name] = true
	wizardOnceDo[name] = prompt
	wizardOnceVal[name] = val
}

func wizardRemember() bool {
	msg.Info("Would you like to remember the previous decision and apply it to future")
	msg.Info("dependencies? Yes (Y) or No (N)")
	return msg.PromptUntilYorN()
}

func wizardAskRange(ver *semver.Version, d *cfg.Dependency) string {
	vstr := ver.String()
	msg.Info("The package %s appears to use semantic versions (http://semver.org).", d.Name)
	msg.Info("Would you like to track the latest minor or patch releases (major.minor.patch)?")
	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" {
		return "m"
	} else if res == "p" || res == "patch" {
		return "p"
	}

	return "s"
}

func wizardAskCurrent(cur string, d *cfg.Dependency) bool {
	msg.Info("The package %s is currently set to use the version %s.", d.Name, d.Reference)
	msg.Info("There is an equivalent semantic version (http://semver.org) release of %s. Would", cur)
	msg.Info("you like to use that instead? Yes (Y) or No (N)")
	return msg.PromptUntilYorN()
}

func wizardAskLatest(latest string, d *cfg.Dependency) bool {
	msg.Info("The package %s appears to have Semantic Version releases (http://semver.org). ", d.Name)
	msg.Info("The latest release is %s. You are currently not using a release. Would you like", latest)
	msg.Info("to use this release? Yes (Y) or No (N)")
	return msg.PromptUntilYorN()
}

func wizardLookInto(d *cfg.Dependency) bool {
	_, err := semver.NewConstraint(d.Reference)

	// The existing version is already a valid semver constraint so we skip suggestions.
	if err == nil {
		return false
	}

	return true
}

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

func wizardFindVersions(d *cfg.Dependency) {
	l, err := cache.Location()
	if err != nil {
		msg.Debug("Problem detecting cache location: %s", err)
		return
	}
	var remote string
	if d.Repository != "" {
		remote = d.Repository
	} else {
		remote = "https://" + d.Name
	}

	key, err := cache.Key(remote)
	if err != nil {
		msg.Debug("Problem generating cache key for %s: %s", remote, err)
		return
	}

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

	var useLocal bool
	if _, err = os.Stat(local); err == nil {
		useLocal = true
	}

	// 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 !useLocal && repo.Vcs() == vcs.Git {
		out, err2 := exec.Command("git", "ls-remote", remote).CombinedOutput()
		if err2 == nil {
			cache.MemTouch(remote)
			cc = false
			lines := strings.Split(string(out), "\n")
			for _, i := range lines {
				ti := strings.TrimSpace(i)
				if found := createGitParseVersion.FindString(ti); found != "" {
					tg := strings.TrimPrefix(strings.TrimSuffix(found, "^{}"), "tags/")
					cache.MemPut(remote, tg)
					if d.Reference != "" && strings.HasPrefix(ti, d.Reference) {
						cache.MemSetCurrent(remote, tg)
					}
				}
			}
		}
	}

	if cc {
		cache.Lock(key)
		cache.MemTouch(remote)
		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.Tags()
		if err != nil {
			msg.Debug("Problem getting tags: %s", err)
		} else {
			for _, v := range tgs {
				cache.MemPut(remote, v)
			}
		}
		if d.Reference != "" && repo.IsReference(d.Reference) {
			tgs, err = repo.TagsFromCommit(d.Reference)
			if err != nil {
				msg.Debug("Problem getting tags for commit: %s", err)
			} else {
				if len(tgs) > 0 {
					for _, v := range tgs {
						if !(repo.Vcs() == vcs.Hg && v == "tip") {
							cache.MemSetCurrent(remote, v)
						}
					}
				}
			}
		}
		cache.Unlock(key)
	}
}

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 ""
}
