package cmd

import (
	"github.com/Masterminds/cookoo"
	"github.com/kylelemons/go-gypsy/yaml"
	"io/ioutil"
	"os"
	"path"
	"strings"
)

// Recurse does glide installs on dependent packages.
//
// Recurse looks in all known packages for a glide.yaml files and installs for
// each one it finds.
//
// The packages scanned can be restricted (at the top level) by providing
// a list of packages to scan in the `packages` param.
//
// Params:
// 	- enable (bool)
// 	- importGodeps (bool)
// 	- importGPM (bool)
// 	- importGb (bool)
// 	- deleteFlatten (bool)
// 	- force (bool)
// 	- packages ([]string): Packages to recurse through. If empty, does all of them.
func Recurse(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	if !p.Get("enable", true).(bool) {
		return nil, nil
	}
	force := p.Get("force", true).(bool)
	plist := p.Get("packages", []string{}).([]string)
	pkgs := list2map(plist)

	godeps, gpm, gb, deleteFlatten := false, false, false, false
	if g, ok := p.Has("importGodeps"); ok {
		godeps = g.(bool)
	}
	if g, ok := p.Has("importGPM"); ok {
		gpm = g.(bool)
	}
	if g, ok := p.Has("importGb"); ok {
		gb = g.(bool)
	}

	if g, ok := p.Has("deleteFlatten"); ok {
		deleteFlatten = g.(bool)
	}

	Info("Checking dependencies for updates. Godeps: %v, GPM: %v, gb: %v\n", godeps, gpm, gb)
	if deleteFlatten == true {
		Info("Deleting flattened dependencies enabled\n")
	}
	conf := p.Get("conf", &Config{}).(*Config)
	vend, _ := VendorPath(c)

	return recDepResolve(conf, pkgs, vend, godeps, gpm, gb, force, deleteFlatten)
}

func recDepResolve(conf *Config, filter map[string]bool, vend string, godeps, gpm, gb, force, deleteFlatten bool) (interface{}, error) {

	Info("Inspecting %s.\n", vend)

	if len(conf.Imports) == 0 {
		Info("No imports.\n")
	}

	restrict := len(filter) > 0

	// Look in each package to see whether it has a glide.yaml, and no vendor/
	for _, imp := range conf.Imports {
		if restrict && !filter[imp.Name] {
			Debug("===> Skipping %q", imp.Name)
			continue
		}
		if imp.Flattened == true {
			continue
		}
		base := path.Join(vend, imp.Name)
		Info("Looking in %s for a glide.yaml file.\n", base)
		if !needsGlideUp(base) {
			if godeps {
				importGodep(base, imp.Name)
			}
			if gpm {
				importGPM(base, imp.Name)
			}
			if gb {
				importGb(base, imp.Name)
			}
			if !needsGlideUp(base) {
				Info("Package %s manages its own dependencies.\n", imp.Name)
				continue
			}
		}

		if err := dependencyGlideUp(conf, base, godeps, gpm, gb, force, deleteFlatten); err != nil {
			Warn("Failed to update dependency %s: %s", imp.Name, err)
		}
	}

	return nil, nil
}

func dependencyGlideUp(parentConf *Config, base string, godep, gpm, gb, force, deleteFlatten bool) error {
	Info("Doing a glide in %s\n", base)
	fname := path.Join(base, "glide.yaml")
	f, err := yaml.ReadFile(fname)
	if err != nil {
		return err
	}

	conf, err := FromYaml(f.Root)
	conf.Parent = parentConf
	if err != nil {
		return err
	}
	for _, imp := range conf.Imports {
		vdir := path.Join(base, "vendor")
		wd := path.Join(vdir, imp.Name)
		// if our root glide.yaml says to flatten this, we skip it
		if dep := conf.GetRoot().Imports.Get(imp.Name); dep != nil {
			flatten := conf.GetRoot().Flatten
			if flatten == true && dep.Flatten == false ||
				flatten == false && dep.Flatten == true {
				flatten = dep.Flatten
			}
			if flatten == true {
				Info("Skipping importing %s due to flatten being set in root import glide.yaml\n", imp.Name)
				imp.Flattened = true
			}

			if flatten == true && imp.Reference != dep.Reference {
				Warn("Flattened package %s ref (%s) is diferent from sub vendored package ref (%s)\n", imp.Name, imp.Reference, dep.Reference)
			}

			if imp.Flattened == true && deleteFlatten == true {
				if exists, _ := fileExist(wd); exists == true || true {
					remove := wd + string(os.PathSeparator)
					Warn("Removing flattened sub vendored package: %s\n", strings.TrimPrefix(remove, base))
					rerr := os.RemoveAll(remove)
					if rerr != nil {
						return rerr
					}
				}
			}
			if imp.Flattened == true {
				continue
			}
		}

		// We don't use the global var to find vendor dir name because the
		// user may mis-use that var to modify the local vendor dir, and
		// we don't want that to break the embedded vendor dirs.

		if err := ensureDir(wd); err != nil {
			Warn("Skipped getting %s (vendor/ error): %s\n", imp.Name, err)
			continue
		}

		if VcsExists(imp, wd) {
			Info("Updating project %s (%s)\n", imp.Name, wd)
			if err := VcsUpdate(imp, vdir, force); err != nil {
				// We can still go on just fine even if this fails.
				Warn("Skipped update %s: %s\n", imp.Name, err)
				continue
			}
		} else {
			Info("Importing %s to project %s\n", imp.Name, base)
			if err := VcsGet(imp, wd); err != nil {
				Warn("Skipped getting %s: %v\n", imp.Name, err)
				continue
			}
		}

		// If a revision has been set use it.
		err = VcsVersion(imp, vdir)
		if err != nil {
			Warn("Problem setting version on %s: %s\n", imp.Name, err)
		}

		//recDepResolve(conf, path.Join(wd, "vendor"))
	}
	// We only filter at the top level.
	e := map[string]bool{}
	recDepResolve(conf, e, path.Join(base, "vendor"), godep, gpm, gb, force, deleteFlatten)
	return nil
}

func ensureDir(dirpath string) error {
	if fi, err := os.Stat(dirpath); err == nil && fi.IsDir() {
		return nil
	}
	return os.MkdirAll(dirpath, 0755)
}

func needsGlideUp(dir string) bool {
	stat, err := os.Stat(path.Join(dir, "glide.yaml"))
	if err != nil || stat.IsDir() {
		return false
	}

	// Should probably see if vendor is there and non-empty.

	return true
}

func importGodep(dir, pkg string) error {
	Info("Looking in %s/Godeps/ for a Godeps.json file.\n", dir)
	d, err := parseGodepGodeps(dir)
	if err != nil {
		Warn("Looking for Godeps: %s\n", err)
		return err
	}
	return quickDirtyYAMLWrite(dir, d, pkg)
}

func importGPM(dir, pkg string) error {
	d, err := parseGPMGodeps(dir)
	if err != nil {
		return err
	}
	return quickDirtyYAMLWrite(dir, d, pkg)
}

func importGb(dir, pkg string) error {
	Info("Looking in %s/vendor/ for a manifest file.\n", dir)
	d, err := parseGbManifest(dir)
	if err != nil {
		return err
	}
	return quickDirtyYAMLWrite(dir, d, pkg)
}

func quickDirtyYAMLWrite(dir string, d []*Dependency, pkg string) error {
	if len(d) == 0 {
		return nil
	}
	c := &Config{Name: pkg, Imports: d}
	node := c.ToYaml()
	data := yaml.Render(node)
	f := path.Join(dir, "glide.yaml")
	Info("Writing new glide.yaml file in %s\n", dir)
	return ioutil.WriteFile(f, []byte(data), 0755)
}
