// This is a simple example
package main

import (
	"os"
	"path/filepath"
	"strings"

	"go.wit.com/lib/gui/repolist"
	"go.wit.com/lib/gui/shell"
	"go.wit.com/log"
)

func doRelease() bool {
	log.Info("doRelease() on", me.current.Name())
	// double check release version logic
	if me.release.releaseVersionB.String() != "release version "+me.release.version.String() {
		log.Warn("something went wrong with the release.version:", me.release.version.String())
		return false
	}
	if strings.HasPrefix(me.release.version.String(), "v") {
		log.Warn("everything is ok. version starts with v.", me.release.version.String())
	} else {
		log.Warn("version does not start with v.", me.release.version.String())
		return false
	}

	curName := me.current.Status.GetCurrentBranchName()
	mName := me.current.Status.GetMasterBranchName()
	if curName != mName {
		log.Info("\trepo is not working from main branch", curName, "!=", mName)
		return false
	}

	if !checkValidGoSum(me.current) {
		return false
	}

	log.Info("\ttag and push", curName, me.release.version.String(), me.releaseReasonS)

	var all [][]string
	all = append(all, []string{"git", "add", "-f", "go.mod"})
	if me.current.Status.IsPrimitive() {
		// don't add go.sum here. TODO: check for go.sum file and fail
	} else {
		all = append(all, []string{"git", "add", "-f", "go.sum"})
	}
	all = append(all, []string{"git", "commit", "-m", me.releaseReasonS})
	all = append(all, []string{"git", "push"})
	all = append(all, []string{"git", "tag", "-m", me.releaseReasonS, me.release.version.String()})
	all = append(all, []string{"git", "push", "origin", me.release.version.String()})

	if !me.current.Status.DoAll(all) {
		log.Info("failed to make new release", me.release.version.String())
		return false
	}
	log.Info("RELEASE OK")

	// 'publish' the version to the golang package versioning system
	if !doPublishVersion() {
		log.Info("PUBLISH FAILED")
		return false
	}

	log.Info("PUBLISH OK")
	me.current.SetGoState("RELEASED")

	// unwind and re-tag. Now that the go.mod and go.sum are published, revert
	// to the development branch
	if !me.current.Status.RevertMasterToDevel() {
		log.Info("Revert Failed")
		return false
	}

	// update tag
	var retag [][]string
	retag = append(retag, []string{"git", "tag", "--delete", me.release.version.String()})
	retag = append(retag, []string{"git", "push", "--delete", "origin", me.release.version.String()})
	retag = append(retag, []string{"git", "tag", "-m", me.releaseReasonS, me.release.version.String()})
	retag = append(retag, []string{"git", "push", "origin", me.release.version.String()})

	if !me.current.Status.DoAll(retag) {
		log.Info("retag failed")
		return false
	}
	log.Info("EVERYTHING OK. RERELEASED", me.current.Name())

	// update the values in the GUI
	me.current.NewScan()

	// attempt to find another repo to release
	if !doReleaseFindNext() {
		log.Info("doReleaseFindNext() could not find a new")
		return false
	}
	log.Info("GOOD TO RUN ANOTHER DAY ON:", me.current.Name())
	return true
}

func checkValidGoSum(repo *repolist.Repo) bool {
	ok, err := me.repos.View.CheckValidGoSum(repo)
	if err != nil {
		log.Info("go mod tidy not ok")
		return false
	}
	if ok {
		log.Info("repo has go.sum requirements that are clean")
		// me.current.setGoSumStatus("CLEAN")
		me.release.status.SetValue("GOOD")
		me.release.notes.SetValue("CheckValidGoSum() does not seem to lie")
		return true
	}
	me.release.notes.SetValue("CheckValidGoSum() failed")
	return false
}

// try to figure out if there is another package to update
func doReleaseFindNext() bool {
	// scan for new repo
	if findNext() {
		log.Info("findNext() found something")
	} else {
		log.Info("findNext() could not find anything")
		return false
	}
	if checkValidGoSum(me.current) {
		return true
	}
	return false
}

// this pulls the new tag from the golang package repository
// to insert the new version
func doPublishVersion() bool {
	gopath := me.current.GoPath()
	cmd := []string{"go", "get", "-v", gopath + "@" + me.release.version.String()}
	log.Info("SHOULD RUN cmd HERE:", cmd)

	// right now, you can't publish this because the go.* files in this project are screwed up
	if me.release.guireleaser == nil {
		log.Info("CAN NOT SELF UPDATE HERE. cmd =", cmd)
		return false
	}
	homeDir, _ := os.UserHomeDir()
	gosum := filepath.Join(homeDir, "go/src/go.wit.com/apps/guireleaser/go.sum")
	if !shell.Exists(gosum) {
		log.Info("go.sum must exist here")
		me.release.guireleaser.Status.MakeRedomod()
	}
	os.Unsetenv("GO111MODULE")
	log.Info("TRYING TO SELF UPDATE HERE. cmd =", cmd)
	err, out := me.release.guireleaser.Status.RunCmd(cmd)
	if gopath == "go.wit.com/apps/guireleaser" {
		// ignore errors on updating myself
		log.Info("IGNORE SELF UPDATE ERROR. cmd =", cmd)
		err = nil
	}
	if err == nil {
		log.Info("SELF UPDATE OK. out =", out)
		log.Info("SELF UPDATE WORKED")
		me.current.SetGoState("RELEASED")
		return true
	}
	return false
}