package main

import (
	"embed"
	"errors"
	"fmt"
	"os"
	"path/filepath"

	"go.wit.com/dev/alexflint/arg"
	"go.wit.com/gui"
	"go.wit.com/lib/fhelp"
	"go.wit.com/lib/gui/shell"
	"go.wit.com/lib/protobuf/forgepb"
	"go.wit.com/lib/protobuf/gitpb"
	"go.wit.com/log"
)

var VERSION string
var ARGNAME string = "guireleaser"

//go:embed resources/*
var resources embed.FS

var argv args

func main() {
	me = new(autoType)

	// parse the command line
	me.pp = arg.MustParse(&argv)

	if argv.Bash {
		argv.doBash()
		os.Exit(0)
	}
	if len(argv.BashAuto) != 0 {
		argv.doBashAuto()
		os.Exit(0)
	}

	// load the ~/.config/forge/ config
	me.forge = forgepb.Init()
	me.found = new(gitpb.Repos)

	fhelp.CheckGoModCleanExit()

	/*
		var bad bool = false
		all := me.forge.Repos.SortByFullPath()
		for all.Scan() {
			repo := all.Next()
			if repo.IsDevelBranch() {
				continue
			}
			log.Info("not on devel branch:", repo.GetCurrentBranchName(), repo.GetDevelBranchName())
			log.Info("not on devel branch:", repo.GetFullPath())
			log.Info("you can not continue if repos are not on devel branches")
			bad = true
		}
		if bad {
			os.Exit(-1)
		}
	*/

	// me.forge.ConfigPrintTable()
	os.Setenv("REPO_WORK_PATH", me.forge.GetGoSrc())

	// save the ENV var here
	me.releaseReasonS = os.Getenv("GUIRELEASE_REASON")

	if me.releaseReasonS == "" {
		badExit(errors.New("shell ENV GUIRELEASE_REASON not set"))
	}

	// unset the go development ENV var to generate release files
	// this is required for go mod init & tidy. Also, if the
	// user drops to a shell or xterm, then they shouldn't be set there either
	os.Unsetenv("GO111MODULE")

	me.myGui = gui.New()
	me.myGui.InitEmbed(resources)
	me.myGui.Default()

	// our main window
	me.mainWindow = me.myGui.NewWindow("GUI release manager " + VERSION)
	me.mainBox = me.mainWindow.NewBox("bw hbox", true)

	// start the http server for polling status
	go startHTTP()

	// sanity check of things that might be around that mess
	// up things later
	// if you have a go.work file, you must delete it
	// TODO: check for go.work files anywhere
	homeDir, _ := os.UserHomeDir()
	gowork := filepath.Join(homeDir, "go/src/go.work")
	if shell.Exists(gowork) {
		badExit(errors.New("go.work must be deleted"))
	}

	log.Info("Creating the Release Window")

	// initialize the repo list window
	// which should be all the git repositories in ~/go/src & the .config file
	me.repos = makeRepoView()

	// the left side of the window options
	globalDisplayOptions(me.mainBox)

	// create the right side of the main window
	createReleaseBox(me.mainBox)

	// disable the open repo button. this isn't really important
	// but does indicates the app (and toolkit) is working
	// this can be removed later, but in these early days, I'm using this
	// tool to release the code for this app, the gui and the gui toolkits
	// and sometimes they lie, don't display stuff, don't even disable things
	// so I can't trust even what I see. It's complicated right now still.
	me.release.openrepo.Disable()

	// disable the gui until the repos are scanned
	me.release.box.Disable()
	me.Disable()

	// scan in the State of all the repos
	// TODO: should not really be necessary directly after init()
	me.repos.View.ScanRepositories()

	// todo: add this to forgepb
	me.startRepo = me.forge.FindWorkingDirRepo()

	if me.startRepo == nil {
		pwd, _ := os.Getwd()
		msg := fmt.Sprint("Can not run if pwd is not a repo", pwd)
		badExit(errors.New(msg))
	}
	me.Enable()

	// set all branches to master & findNext()
	makePrepareRelease()

	// intermittently scans the status indefinitly
	me.repos.View.Watchdog(func() {
		log.Info("In main()")
		// processing is done. update the repo summary box
		// me.summary.Update()
	})
}