package cmd

import (
	"fmt"
	"os"
	"path"
	"runtime"
	"strings"

	"github.com/Masterminds/cookoo"
	"golang.org/x/tools/go/vcs"
)

const (
	NoVCS = ""
	Git   = "git"
	Bzr   = "bzr"
	Hg    = "hg"
	Svn   = "svn"
)

// Get fetches a single package and puts it in vendor/.
//
// Params:
//	- package (string): Name of the package to get.
// 	- verbose (bool): default false
//
// Returns:
// 	- *Dependency: A dependency describing this package.
func Get(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	name := p.Get("package", "").(string)
	cfg := p.Get("conf", nil).(*Config)
	verbose := p.Get("verbose", false).(bool)

	cwd, err := VendorPath(c)
	if err != nil {
		return nil, err
	}

	repo, err := vcs.RepoRootForImportPath(name, verbose)
	if err != nil {
		return nil, err
	}

	if cfg.HasDependency(repo.Root) {
		return nil, fmt.Errorf("Package '%s' is already in glide.yaml", repo.Root)
	}

	if len(repo.Root) == 0 {
		return nil, fmt.Errorf("Package name is required.")
	}

	dep := &Dependency{
		Name:       repo.Root,
		VcsType:    repo.VCS.Cmd,
		Repository: repo.Repo,
	}
	subpkg := strings.TrimPrefix(name, repo.Root)
	if len(subpkg) > 0 && subpkg != "/" {
		dep.Subpackages = []string{subpkg}
	}

	dest := path.Join(cwd, repo.Root)
	if err := repo.VCS.Create(dest, repo.Repo); err != nil {
		return dep, err
	}

	cfg.Imports = append(cfg.Imports, dep)

	return dep, nil
}

// GetImports iterates over the imported packages and gets them.
func GetImports(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	cfg := p.Get("conf", nil).(*Config)
	cwd, err := VendorPath(c)
	if err != nil {
		Error("Failed to prepare vendor directory: %s", err)
		return false, err
	}

	if len(cfg.Imports) == 0 {
		Info("No dependencies found. Nothing downloaded.\n")
		return false, nil
	}

	for _, dep := range cfg.Imports {
		if err := VcsGet(dep, cwd); err != nil {
			Warn("Skipped getting %s: %s\n", dep.Name, err)
		}
	}

	return true, nil
}

// UpdateImports iterates over the imported packages and updates them.
func UpdateImports(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	cfg := p.Get("conf", nil).(*Config)
	cwd, err := VendorPath(c)
	if err != nil {
		return false, err
	}

	if len(cfg.Imports) == 0 {
		Info("No dependencies found. Nothing updated.\n")
		return false, nil
	}

	for _, dep := range cfg.Imports {
		if err := VcsUpdate(dep, cwd); err != nil {
			Warn("Update failed for %s: %s\n", dep.Name, err)
		}
	}

	return true, nil
}

func SetReference(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	cfg := p.Get("conf", nil).(*Config)
	cwd, err := VendorPath(c)
	if err != nil {
		return false, err
	}

	if len(cfg.Imports) == 0 {
		Info("No references set.\n")
		return false, nil
	}

	for _, dep := range cfg.Imports {
		if err := VcsVersion(dep, cwd); err != nil {
			Warn("Failed to set version on %s to %s: %s\n", dep.Name, dep.Reference, err)
		}
	}

	return true, nil
}

var (
	goGet VCS = new(GoGetVCS)
	git   VCS = new(GitVCS)
	svn   VCS = new(SvnVCS)
	bzr   VCS = new(BzrVCS)
	hg    VCS = new(HgVCS)
)

// filterArchOs indicates a dependency should be filtered out because it is
// the wrong GOOS or GOARCH.
func filterArchOs(dep *Dependency) bool {
	found := false
	if len(dep.Arch) > 0 {
		for _, a := range dep.Arch {
			if a == runtime.GOARCH {
				found = true
			}
		}
		// If it's not found, it should be filtered out.
		if !found {
			return true
		}
	}

	found = false
	if len(dep.Os) > 0 {
		for _, o := range dep.Os {
			if o == runtime.GOOS {
				found = true
			}
		}
		if !found {
			return true
		}

	}

	return false
}

// VcsGet figures out how to fetch a dependency, and then gets it.
//
// VcsGet installs into the dest.
func VcsGet(dep *Dependency, dest string) error {

	cmd, err := dep.VCSCmd()
	if err != nil {
		Error("Could not resolve repository %s\n", dep.Name)
	}

	if dep.Repository == "" {
		dep.Repository = "https://" + dep.Name
	}

	if err := cmd.Create(dest, dep.Repository); err != nil {
		return err
	}

	return nil
}

// VcsUpdate updates to a particular checkout based on the VCS setting.
// TODO: The command from go tools checks out a specific hash which causes
// problems on future updates. Need to fix.
func VcsUpdate(dep *Dependency, vend string) error {
	Info("Fetching updates for %s.\n", dep.Name)

	if filterArchOs(dep) {
		Info("%s is not used for %s/%s.\n", dep.Name, runtime.GOOS, runtime.GOARCH)
		return nil
	}

	dest := path.Join(vend, dep.Name)
	// If destination doesn't exist we need to perform an initial checkout.
	if _, err := os.Stat(dest); os.IsNotExist(err) {
		if err = VcsGet(dep, dest); err != nil {
			Warn("Unable to checkout %s\n", dep.Name)
			fmt.Println(err)
			return err
		}
	} else {
		cmd, err := dep.VCSCmd()
		if err != nil {
			return err
		}
		// TODO: Handle the case of a VCS switching. The could be the config
		// for a VCS or the type of VCS.
		if err := cmd.Download(dest); err != nil {
			Warn("Download failed.\n")
			return err
		}
	}

	return nil
}

func VcsVersion(dep *Dependency, vend string) error {
	// If there is no refernece configured there is nothing to set.
	if dep.Reference == "" {
		return nil
	}

	Info("Setting version for %s.\n", dep.Name)

	cwd := path.Join(vend, dep.Name)
	cmd, err := dep.VCSCmd()
	if err != nil {
		return err
	}

	// TagSync assumes the remote for Git is the origin. Doesn't
	// work with non-origin remotes.
	if err := cmd.TagSync(cwd, dep.Reference); err != nil {
		Error("Failed to sync to %s: %s\n", dep.Reference, err)
		return err
	}

	if cmd.Cmd == "git" {
		Info("XXX: Implement history-since function.\n")
	}

	return nil
}

func VcsLastCommit(dep *Dependency) (string, error) {

	cmd, err := dep.VCSCmd()
	if err != nil {
		return "", err
	}

	switch cmd.Cmd {
	case Git:
		return git.LastCommit(dep)
	case Bzr:
		return bzr.LastCommit(dep)
	case Hg:
		return hg.LastCommit(dep)
	case Svn:
		return svn.LastCommit(dep)
	default:
		if len(dep.Reference) > 0 {
			Error("Cannot update %s to specific version with VCS %d.\n", dep.Name, dep.VcsType)
		}
		return "", nil
	}
}

func VcsSetReference(dep *Dependency) error {
	Warn("Cannot set reference. not implemented.\n")
	return nil
}

// GuessVCS attempts to guess guess the VCS used by a package.
func GuessVCS(dep *Dependency) (string, error) {
	cmd, err := dep.VCSCmd()
	if err != nil {
		return "", err
	}
	return cmd.Cmd, nil
}
