package forgepb

import (
	"errors"

	"go.wit.com/lib/protobuf/gitpb"
	"go.wit.com/log"
)

func (f *Forge) GitPull() bool {
	f.Repos.RillGitPull(5, 5)
	/*

		var localonly int
		var badmap int

		log.Log(WARN, "running git pull everywhere")
		var failed int = 0
		for all.Scan() {
			repo := all.Next()
			if out, err := repo.GitPull(); err == nil {
				log.Log(WARN, "Ran git pull ok", repo.GetGoPath(), out)
			} else {
				failed += 1
				// repo.DumpTags()
				if errors.Is(repostatus.ErrorGitPullOnLocal, err) {
					localonly += 1
					continue
				}
				badmap += 1
				log.Log(WARN, "bad unknown git error", repo.GetGoPath(), out, err)
			}
		}
		log.Log(WARN, "Ran git pull in all repos. failure count =", failed)
		log.Log(WARN, "Ran git pull in all repos. bad errors =", badmap)
		if localonly != 0 {
			log.Log(WARN, "Ran git pull in all repos. ignored local only branches =", localonly)
		}
	*/
	return true
}

func (f *Forge) CheckoutDevel() bool {
	log.Log(WARN, "running git checkout devel everwhere")
	var failed int = 0
	var count int = 0
	all := f.Repos.SortByFullPath()
	for all.Scan() {
		repo := all.Next()
		count += 1
		if repo.CheckoutDevel() {
			// checkout ok
		} else {
			dname := repo.GetDevelBranchName()
			if err := f.makeBranch(repo, dname); err != nil {
				log.Info(repo.GetGoPath(), "can not make devel branch", dname)
				failed += 1
			}
		}
	}
	log.Log(WARN, "Ran git checkout in", count, "repos. failure count =", failed)
	return true
}

func (f *Forge) MakeDevelBranch(repo *gitpb.Repo) error {
	dname := repo.GetDevelBranchName()
	if dname == "" {
		dname = f.configDevelBranchName(repo)
	}
	if err := f.makeBranch(repo, dname); err != nil {
		return err
	}
	repo.DevelBranchName = dname
	return nil
}

func (f *Forge) MakeUserBranch(repo *gitpb.Repo) error {
	uname := repo.GetUserBranchName()
	if uname == "" {
		uname = f.configUserBranchName(repo)
	}
	if err := f.makeBranch(repo, uname); err != nil {
		return err
	}
	repo.UserBranchName = uname
	return nil
}

func (f *Forge) makeBranch(repo *gitpb.Repo, bname string) error {
	if repo.IsLocalBranch(bname) {
		// branch already exists in refs/heads/
		return nil
	}
	if repo.IsBranch(bname) {
		// branch already exists refs/remotes/
		return nil
	} else {
		log.Info("makeBranch() says", bname, "does not exist")
		loop := repo.Tags.All()
		for loop.Scan() {
			t := loop.Next()
			log.Info("LocalTagExists() tag:", t.Refname)
		}
	}
	mname := repo.GetMasterBranchName()
	cname := repo.GetCurrentBranchName()
	if mname != cname {
		return errors.New("can only make branches from master branch")
	}
	cmd := []string{"git", "branch", bname}
	if err := repo.StrictRun(cmd); err != nil {
		return err
	}
	return nil
}

func (f *Forge) CheckoutMaster() bool {
	log.Log(WARN, "running git checkout master everwhere")
	var failed int = 0
	var count int = 0
	all := f.Repos.SortByFullPath()
	for all.Scan() {
		repo := all.Next()
		count += 1
		if repo.CheckoutMaster() {
			// checkout ok
		} else {
			failed += 1
		}
	}
	log.Log(WARN, "Ran git checkout in", count, "repos. failure count =", failed)
	return true
}

func (f *Forge) CheckoutUser() bool {
	log.Log(WARN, "running git checkout user everwhere")
	var failed int = 0
	var count int = 0
	all := f.Repos.SortByFullPath()
	for all.Scan() {
		repo := all.Next()
		if repo.GetCurrentBranchName() == repo.GetUserBranchName() {
			// already on the user branch
			continue
		}
		count += 1
		if repo.CheckoutUser() {
			// checkout ok
		} else {
			failed += 1
		}
	}
	log.Log(WARN, "Ran git checkout in", count, "repos. failure count =", failed)
	return true
}

func (f *Forge) CheckoutUserForce() bool {
	log.Log(WARN, "running git checkout user everwhere")
	var failed int = 0
	var count int = 0
	all := f.Repos.SortByFullPath()
	for all.Scan() {
		repo := all.Next()
		count += 1
		if repo.CheckoutUser() {
			// checkout ok
		} else {
			failed += 1
		}
	}
	log.Log(WARN, "Ran git checkout in", count, "repos. failure count =", failed)
	return true
}