package cmd

import (
	"errors"
	"fmt"
	"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
	}

	Warn("Lockfile hash: %s", lock.Hash)
	Warn("glide.yaml generated hash: %s", hash)
	y, _ := conf.Marshal()
	fmt.Println(y)

	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)
	useGopath := p.Get("useGopath", 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, useGopath); 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, useGopath); 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
}
