package cmd

import (
	"errors"
	"io/ioutil"
	"os"
	"sync"

	"github.com/Masterminds/cookoo"
	"github.com/Masterminds/glide/cfg"
)

// LockFileExists checks if a lock file exists. If not it jumps to the update
// command.
func LockFileExists(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	fname := p.Get("filename", "glide.lock").(string)
	if _, err := os.Stat(fname); err != nil {
		Info("Lock file (glide.lock) does not exist. Performing update.")
		return false, &cookoo.Reroute{"update"}
	}

	return true, nil
}

// LoadLockFile loads the lock file to the context and checks if it is correct
// for the loaded cfg file.
func LoadLockFile(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	fname := p.Get("filename", "glide.lock").(string)
	conf := p.Get("conf", nil).(*cfg.Config)

	yml, err := ioutil.ReadFile(fname)
	if err != nil {
		return nil, err
	}
	lock, err := cfg.LockfileFromYaml(yml)
	if err != nil {
		return nil, err
	}

	hash, err := conf.Hash()
	if err != nil {
		return nil, err
	}

	if hash != lock.Hash {
		return nil, errors.New("Lock file does not match YAML configuration. Consider running 'update'")
	}

	return lock, nil
}

// Install installs the dependencies from a Lockfile.
func Install(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	lock := p.Get("lock", nil).(*cfg.Lockfile)
	conf := p.Get("conf", nil).(*cfg.Config)
	force := p.Get("force", true).(bool)
	home := p.Get("home", "").(string)
	cache := p.Get("cache", false).(bool)
	cacheGopath := p.Get("cacheGopath", false).(bool)
	skipGopath := p.Get("skipGopath", false).(bool)

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

	// Create a config setup based on the Lockfile data to process with
	// existing commands.
	newConf := &cfg.Config{}
	newConf.Name = conf.Name

	newConf.Imports = make(cfg.Dependencies, len(lock.Imports))
	for k, v := range lock.Imports {
		newConf.Imports[k] = &cfg.Dependency{
			Name:        v.Name,
			Reference:   v.Version,
			Repository:  v.Repository,
			VcsType:     v.VcsType,
			Subpackages: v.Subpackages,
			Arch:        v.Arch,
			Os:          v.Os,
		}
	}

	newConf.DevImports = make(cfg.Dependencies, len(lock.DevImports))
	for k, v := range lock.DevImports {
		newConf.DevImports[k] = &cfg.Dependency{
			Name:        v.Name,
			Reference:   v.Version,
			Repository:  v.Repository,
			VcsType:     v.VcsType,
			Subpackages: v.Subpackages,
			Arch:        v.Arch,
			Os:          v.Os,
		}
	}

	newConf.DeDupe()

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

	// for _, dep := range newConf.Imports {
	// 	if err := VcsUpdate(dep, cwd, home, force, cache, cacheGopath, skipGopath); err != nil {
	// 		Warn("Update failed for %s: %s\n", dep.Name, err)
	// 	}
	// }

	done := make(chan struct{}, concurrentWorkers)
	in := make(chan *cfg.Dependency, concurrentWorkers)
	var wg sync.WaitGroup

	for i := 0; i < concurrentWorkers; i++ {
		go func(ch <-chan *cfg.Dependency) {
			for {
				select {
				case dep := <-ch:
					if err := VcsUpdate(dep, cwd, home, force, cache, cacheGopath, skipGopath); err != nil {
						Warn("Update failed for %s: %s\n", dep.Name, err)
					}
					wg.Done()
				case <-done:
					return
				}
			}
		}(in)
	}

	for _, dep := range newConf.Imports {
		wg.Add(1)
		in <- dep
	}

	wg.Wait()
	// Close goroutines setting the version
	for i := 0; i < concurrentWorkers; i++ {
		done <- struct{}{}
	}

	return newConf, nil
}
