package action

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/Masterminds/glide/cache"
	"github.com/Masterminds/glide/cfg"
	"github.com/Masterminds/glide/dependency"
	"github.com/Masterminds/glide/msg"
	gpath "github.com/Masterminds/glide/path"
	"github.com/Masterminds/glide/repo"
	"github.com/Masterminds/glide/util"
	"github.com/Masterminds/semver"
	"github.com/sdboyer/gps"
)

// Get fetches one or more dependencies and installs.
//
// This includes a solver run and re-generating the lock file.
func Get(names []string, installer *repo.Installer, stripVendor, nonInteract bool) {
	base := gpath.Basepath()
	EnsureGopath()
	EnsureVendorDir()
	conf := EnsureConfig()

	glidefile, err := gpath.Glide()
	if err != nil {
		msg.Die("Could not find Glide file: %s", err)
	}

	vend, err := gpath.Vendor()
	if err != nil {
		msg.Die("Could not find the vendor dir: %s", err)
	}

	params := gps.SolveParameters{
		RootDir:     filepath.Dir(glidefile),
		ImportRoot:  gps.ProjectRoot(conf.ProjectRoot),
		Manifest:    conf,
		Trace:       true,
		TraceLogger: log.New(os.Stdout, "", 0),
	}

	// We load the lock file early and bail out if there's a problem, because we
	// don't want a get to just update all deps without the user explictly
	// making that choice.
	if gpath.HasLock(base) {
		params.Lock, err = loadLockfile(base, conf)
		if err != nil {
			msg.Err("Could not load lockfile; aborting get. Existing dependency versions cannot be safely preserved without a lock file. Error was: %s", err)
			return
		}
	}

	// Create the SourceManager for this run
	sm, err := gps.NewSourceManager(dependency.Analyzer{}, filepath.Join(installer.Home, "cache"), false)
	defer sm.Release()
	if err != nil {
		msg.Err(err.Error())
		return
	}

	// Now, with the easy/fast errors out of the way, dive into adding the new
	// deps to the manifest.

	// Add the packages to the config.
	//if count, err2 := addPkgsToConfig(conf, names, insecure, nonInteract, testDeps); err2 != nil {
	if count, err2 := addPkgsToConfig(conf, names, false, nonInteract, false); err2 != nil {
		msg.Die("Failed to get new packages: %s", err2)
	} else if count == 0 {
		msg.Warn("Nothing to do")
		return
	}

	// Prepare a solver. This validates our params.
	s, err := gps.Prepare(params, sm)
	if err != nil {
		msg.Err("Aborted get - could not set up solver to reconcile dependencies: %s", err)
		return
	}

	r, err := s.Solve()
	if err != nil {
		// TODO better error handling
		msg.Err("Failed to find a solution for all new dependencies: %s", err.Error())
		return
	}

	// Solve succeeded. Write out the yaml, lock, and vendor to a tmpdir, then mv
	// them all into place iff all the writes worked

	gw := safeGroupWriter{
		conf:        conf,
		lock:        params.Lock.(*cfg.Lockfile),
		resultLock:  r,
		sm:          sm,
		glidefile:   glidefile,
		vendor:      vend,
		stripVendor: stripVendor,
	}

	err = gw.writeAllSafe()
	if err != nil {
		msg.Err(err.Error())
		return
	}
}

func writeLock(conf, confcopy *cfg.Config, base string) {
	hash, err := conf.Hash()
	if err != nil {
		msg.Die("Failed to generate config hash. Unable to generate lock file.")
	}
	lock, err := cfg.NewLockfile(confcopy.Imports, confcopy.DevImports, hash)
	if err != nil {
		msg.Die("Failed to generate lock file: %s", err)
	}
	if err := lock.WriteFile(filepath.Join(base, gpath.LockFile)); err != nil {
		msg.Die("Failed to write glide lock file: %s", err)
	}
}

// addPkgsToConfig adds the given packages to the config file.
//
// Along the way it:
// - ensures that this package is not in the ignore list
// - checks to see if this is already in the dependency list.
// - splits version of of package name and adds the version attribute
// - separates repo from packages
// - sets up insecure repo URLs where necessary
// - generates a list of subpackages
func addPkgsToConfig(conf *cfg.Config, names []string, insecure, nonInteract, testDeps bool) (int, error) {
	// TODO refactor this to take and use a gps.SourceManager
	if len(names) == 1 {
		msg.Info("Preparing to install %d package.", len(names))
	} else {
		msg.Info("Preparing to install %d packages.", len(names))
	}
	numAdded := 0
	for _, name := range names {
		var version string
		parts := strings.Split(name, "#")
		if len(parts) > 1 {
			name = parts[0]
			version = parts[1]
		}

		msg.Info("Attempting to get package %s", name)

		root, subpkg := util.NormalizeName(name)
		if len(root) == 0 {
			return 0, fmt.Errorf("Package name is required for %q.", name)
		}

		if conf.HasDependency(root) {

			var moved bool
			var dep *cfg.Dependency
			// Move from DevImports to Imports
			if !testDeps && !conf.Imports.Has(root) && conf.DevImports.Has(root) {
				dep = conf.DevImports.Get(root)
				conf.Imports = append(conf.Imports, dep)
				conf.DevImports = conf.DevImports.Remove(root)
				moved = true
				numAdded++
				msg.Info("--> Moving %s from testImport to import", root)
			} else if testDeps && conf.Imports.Has(root) {
				msg.Warn("--> Test dependency %s already listed as import", root)
			}

			// Check if the subpackage is present.
			if subpkg != "" {
				if dep == nil {
					dep = conf.Imports.Get(root)
					if dep == nil && testDeps {
						dep = conf.DevImports.Get(root)
					}
				}
				if dep.HasSubpackage(subpkg) {
					if !moved {
						msg.Warn("--> Package %q is already in glide.yaml. Skipping", name)
					}
				} else {
					dep.Subpackages = append(dep.Subpackages, subpkg)
					msg.Info("--> Adding sub-package %s to existing import %s", subpkg, root)
					numAdded++
				}
			} else if !moved {
				msg.Warn("--> Package %q is already in glide.yaml. Skipping", root)
			}
			continue
		}

		if conf.HasIgnore(root) {
			msg.Warn("--> Package %q is set to be ignored in glide.yaml. Skipping", root)
			continue
		}

		dep := &cfg.Dependency{
			Name:       root,
			Constraint: gps.Any(),
		}

		// When retriving from an insecure location set the repo to the
		// insecure location.
		if insecure {
			dep.Repository = "http://" + root
		}

		if version != "" {
			dep.Reference = version
		} else if !nonInteract {
			getWizard(dep)
		}

		if len(subpkg) > 0 {
			dep.Subpackages = []string{subpkg}
		}

		if dep.Reference != "" {
			msg.Info("--> Adding %s to your configuration with the version %s", dep.Name, dep.Reference)
		} else {
			msg.Info("--> Adding %s to your configuration", dep.Name)
		}

		if testDeps {
			conf.DevImports = append(conf.DevImports, dep)
		} else {
			conf.Imports = append(conf.Imports, dep)
		}
		numAdded++
	}
	return numAdded, nil
}

func getWizard(dep *cfg.Dependency) {
	var remote string
	if dep.Repository != "" {
		remote = dep.Repository
	} else {
		remote = "https://" + dep.Name
	}

	// Lookup dependency info and store in cache.
	msg.Info("--> Gathering release information for %s", dep.Name)
	wizardFindVersions(dep)

	memlatest := cache.MemLatest(remote)
	if memlatest != "" {
		dres := wizardAskLatest(memlatest, dep)
		if dres {
			dep.Reference = memlatest

			sv, err := semver.NewVersion(dep.Reference)
			if err == nil {
				res := wizardAskRange(sv, dep)
				if res == "m" {
					dep.Reference = "^" + sv.String()
				} else if res == "p" {
					dep.Reference = "~" + sv.String()
				}
			}
		}
	}
}
