package cmd

import (
	"github.com/Masterminds/cookoo"
	"os"
	"strings"
)

// GuessDeps tries to get the dependencies for the current directory.
//
// Params
// 	- dirname (string): Directory to use as the base. Default: "."
func GuessDeps(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	buildContext, err := GetBuildContext()
	if err != nil {
		return nil, err
	}
	base := p.Get("dirname", ".").(string)
	deps := make(map[string]bool)
	err = findDeps(buildContext, deps, base, "")
	deps = compactDeps(deps)
	delete(deps, base)
	if err != nil {
		return nil, err
	}

	config := new(Config)

	// Get the name of the top level package
	config.Name = guessPackageName(buildContext, base)
	config.Imports = make([]*Dependency, len(deps))
	i := 0
	for pa := range deps {
		Info("Found reference to %s\n", pa)
		d := &Dependency{
			Name: pa,
		}
		config.Imports[i] = d
		i++
	}

	return config, nil
}

// findDeps finds all of the dependenices.
// https://golang.org/src/cmd/go/pkg.go#485
//
// As of Go 1.5 the go command knows about the vendor directory but the go/build
// package does not. It only knows about the GOPATH and GOROOT. In order to look
// for packages in the vendor/ directory we need to fake it for now.
func findDeps(b *BuildCtxt, soFar map[string]bool, name, vpath string) error {
	cwd, err := os.Getwd()
	if err != nil {
		return err
	}

	// Skip cgo pseudo-package.
	if name == "C" {
		return nil
	}

	pkg, err := b.Import(name, cwd, 0)
	if err != nil {
		return err
	}

	if pkg.Goroot {
		return nil
	}

	if vpath == "" {
		vpath = pkg.ImportPath
	}

	// When the vendor/ directory is present make sure we strip it out before
	// registering it as a guess.
	realName := strings.TrimPrefix(pkg.ImportPath, vpath+"/vendor/")

	// Before adding a name to the list make sure it's not the name of the
	// top level package.
	lookupName, _ := NormalizeName(realName)
	if vpath != lookupName {
		soFar[realName] = true
	}
	for _, imp := range pkg.Imports {
		if !soFar[imp] {

			// Try looking for a dependency as a vendor. If it's not there then
			// fall back to a way where it will be found in the GOPATH or GOROOT.
			if err := findDeps(b, soFar, vpath+"/vendor/"+imp, vpath); err != nil {
				if err := findDeps(b, soFar, imp, vpath); err != nil {
					return err
				}
			}
		}
	}
	return nil
}

// compactDeps registers only top level packages.
//
// Minimize the package imports. For example, importing github.com/Masterminds/cookoo
// and github.com/Masterminds/cookoo/io should not import two packages. Only one
// package needs to be referenced.
func compactDeps(soFar map[string]bool) map[string]bool {
	basePackages := make(map[string]bool, len(soFar))
	for k := range soFar {
		base, _ := NormalizeName(k)
		basePackages[base] = true
	}

	return basePackages
}

// Attempt to guess at the package name at the top level. When unable to detect
// a name goes to default of "main".
func guessPackageName(b *BuildCtxt, base string) string {
	cwd, err := os.Getwd()
	if err != nil {
		return "main"
	}

	pkg, err := b.Import(base, cwd, 0)
	if err != nil {
		return "main"
	}

	return pkg.ImportPath
}
