// Copyright 2024 WIT.COM Inc Licensed GPL 3.0

package main

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

	"go.wit.com/dev/alexflint/arg"
	"go.wit.com/log"
)

var Version string

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

func main() {
	if os.Getenv("VIRTIGO_HOME") == "" {
		homeDir, _ := os.UserHomeDir()
		fullpath := filepath.Join(homeDir, ".config/virtigo")
		os.Setenv("VIRTIGO_HOME", fullpath)
	}
	pp := arg.MustParse(&argv)

	if !argv.Uptime {
		pp.WriteHelp(os.Stdout)
		os.Exit(0)
	}

	if argv.Daemon {
		log.DaemonMode(true)
	}

	// set defaults
	me.unstable = time.Now()   // initialize the grid as unstable
	me.delay = 5 * time.Second // how often to poll the hypervisors
	me.changed = false

	cfgfile()

	var ok bool = true
	for _, filename := range argv.Xml {
		domcfg, err := readXml(filename)
		if err != nil {
			// parsing the libvirt xml file failed
			log.Info("error:", filename, err)
			ok = false
			continue
		}
		// see if the libvirt xml droplet is already here
		d, err := findDomain(domcfg)
		if err != nil {
			// some error. probably UUID mismatch or hostname duplication
			// this has to be fixed by hand
			ok = false
			continue
		}
		if d == nil {
			// this is a new droplet. add it to the cluster
			log.Info("Add New Droplet here", domcfg.Name)
			_, err := addDomainDroplet(domcfg)
			if err != nil {
				ok = false
				log.Info("addDomainDroplet() failed", err)
			}
		} else {
			// this droplet is already here
			if updateDroplet(d, domcfg) {
				if me.changed {
					log.Info("updateDroplet() worked. droplet changed")
				} else {
					log.Info(filename, "nothing changed")
				}
			} else {
				log.Info("updateDroplet() failed for", d.pb.Hostname)
				ok = false
			}
		}
	}
	if len(argv.Xml) != 0 {
		if me.changed {
			if argv.Save {
				writeConfigFile()
				writeConfigFileDroplets()
			} else {
				log.Info("Not saving changes (use --save to save)")
			}
		}
		if !ok {
			log.Info("adding xml files failed")
			os.Exit(-1)
		}
		os.Exit(0)
	}

	/*
		log.Info("command line hypervisors:", argv.Hosts)
		for _, name := range argv.Hosts {
			h := findHypervisor(name)
			if h != nil {
				log.Info("command line hypervisor", name, "already in config file")
				continue
			}
			h = addHypervisor(name)
			h.pb.Active = true
		}
	*/

	// start the watchdog polling for each hypervisor
	for _, h := range me.hypers {
		log.Info("starting polling on", h.pb.Hostname)
		go h.NewWatchdog()
	}

	// sit here
	startHTTP()
}

func makeDroplet(start string) {
	d := findDroplet(start)
	if d == nil {
		log.Info("droplet is unknown:", start)
		os.Exit(0)
	}
	log.Info("start droplet here:", d.pb.Hostname)
	domcfg := makeStandardXml(d)

	fmt.Printf("Virt type %s\n", domcfg.Type)
	fmt.Printf("Virt name %s\n", domcfg.Name)
	fmt.Printf("Virt UUID %s\n", domcfg.UUID)
	fmt.Printf("Virt Memory %d %s\n", domcfg.Memory.Value, domcfg.Memory.Unit)

	// test add some ethernet devices
	macs := getMacs(domcfg)
	fmt.Printf("Virt mac addr:%s\n", macs)

	// clearEthernet(domcfg)

	addEthernet(domcfg, "04:44:33:11:22:11", "worldbr")
	addEthernet(domcfg, "04:44:33:33:44:55", "greenbr")

	// add a check here to make these unique
	// setRandomMacs(domcfg)

	// print out the final mac addresses
	macs = getMacs(domcfg)
	fmt.Printf("Virt mac addr:%s\n", macs)

	qcow := "/home/nfs/" + d.pb.Hostname + ".qcow2"
	setSimpleDisk(domcfg, qcow)

	writeoutXml(domcfg, "blahcarr")
	os.Exit(0)
}