package main

/* 
	This simply parses the command line arguments using the default golang
	package called 'flag'. This can be used as a simple template to parse
	command line arguments in other programs.

	It puts everything in a 'config' Protobuf which I think is a good
	wrapper around the 'flags' package and doesn't need a whole mess of
	global variables
*/

import "log"
import "os"
import "os/user"
import "flag"
import "fmt"
import "runtime"
import "io/ioutil"
import "strings"

import "github.com/golang/protobuf/jsonpb"
import pb "git.wit.com/wit/witProtobuf"

import "github.com/davecgh/go-spew/spew"

var config *pb.Config

// This loads the config file and marshals it into the
// config protocol buffer definition.
// Then it is very easy to pass all the config options
// around and the re-write that JSON file when the GUI
// exits
func loadConfigFile() {
	// look up the user information
	user, err := user.Current()
	if err != nil {
		onExit(err)
	}
	spew.Dump(user)

	filename := ""
	// TODO: confirm this is correct for MacOS and Windows
	if runtime.GOOS == "linux" {
		log.Println("loadConfigFile() OS: Linux")
		filename = user.HomeDir + "/.config/cloud-control-panel.json"
	} else if runtime.GOOS == "windows" {
		log.Println("loadConfigFile() OS: Windows")
		filename = user.HomeDir + "\\cloud-control-panel.json"
	} else {
		log.Println("loadConfigFile() OS: " + runtime.GOOS)
		filename = user.HomeDir + "/.cloud-control-panel.json"
	}

	tmp := loadConfigFromFilename(filename)
	config = &tmp

	config.Filename = filename
}

var customUsage = func() {
	fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s:\n", os.Args[0])
	flag.PrintDefaults()

	fmt.Println("")
	fmt.Println("EXAMPLES:")
	fmt.Println("")
	fmt.Println(os.Args[0] + " --hostname test.hostname.wit.com")
	fmt.Println("")
}
var defaultconfig	*bool

func parseFlags() {
	var hostname	string

	// always override the debugging flag from the command line
	var debug	*bool
	var debugtable	*bool

	flag.StringVar  (&hostname,      "hostname",      "localhost",  "Your full hostname")

	height		:= flag.Int ("height",            0,            "Height of the Window")
	width		:= flag.Int ("width",             0,            "Width of the Window")
	debug		 = flag.Bool("debug",             false,        "Enable debugging")
	defaultconfig	 = flag.Bool("defaultconfig",     false,        "Use the default config file")
	debugtable	 = flag.Bool("debugtable",        false,        "Enable GUI table debugging")

	// Set the output if something fails to stdout rather than stderr
	flag.CommandLine.SetOutput(os.Stdout)

	flag.Usage = customUsage
	flag.Parse()

	if flag.Parsed() {
		log.Println("flag.Parse() worked")
	} else {
		log.Println("flag.Parse() failed")
		onExit(nil)
	}

	if (*width > 100) {
		log.Println("ENABLE width =", int32(*width))
		config.Width  = int32(*width)
	}
	if (*height > 100) {
		log.Println("ENABLE height =", int32(*height))
		config.Height = int32(*height)
	}

	if (hostname == "") {
		config.Hostname = hostname
	}

	// never allow these to be set in the config file
	config.Debug       = *debug
	config.Debugtable  = *debugtable
}

// Convert a Protobuf to JSON
func PBtoJSON() string {
	// this makes a sample protobuf
	c := pb.MakeDefaultConfig()

	marshaler := &jsonpb.Marshaler{}
	stuff, _ := marshaler.MarshalToString(c)
	log.Println(stuff)
	return stuff
}

func writeToFile(filename string, a string) {
	f, _ := os.Create(filename)
	f.WriteString(a)
	f.Close()
}

func saveConfig() {
	filename := config.Filename
	if (filename == "") {
		log.Println("NOT SAVING CONFIG FILE")
	} else {
		marshaler := &jsonpb.Marshaler{}
		stuff, _ := marshaler.MarshalToString(config)
		log.Println(stuff)

		writeToFile(filename, stuff)
	}
}

// will load the default config from within the go binary
func loadConfigFromFilename(filename string) pb.Config {
	sets := pb.Config{}
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Println("ioutil.ReadFile() ERROR =", err)
		// This probably means this is the first time the user is opening this
		sets.Errors += 1
		sets.Crash = "err"
		sets.Counter = 1
		sets.Width = 500
		sets.Height = 500
		return sets
	}
	log.Println("ioutil.ReadFile() b =", b)

	err = jsonpb.Unmarshal(strings.NewReader(string(b)), &sets)
	if err != nil {
		log.Println("jsonpb.Unmarshal() ERROR =", err)
	}
	spew.Dump(sets)
	return sets
}

// will load the default config from within the go binary
func loadDefaultConfig() *pb.Config {
	log.Println("TRY TO LOAD DEFAULT CONFIG")
	// defaultConfig, _ := packrBox.FindString("protobuf-config.json")
	b, err := packrBox.FindString("cloud-control-panel.json")
	log.Println("b =", b)
	log.Println("err =", err)
	// var newpb *pb.Config
	sets := pb.Config{}

	err = jsonpb.Unmarshal(strings.NewReader(string(b)), &sets)
	if err != nil {
		log.Println("jsonpb.Unmarshal() ERROR =", err)
	}
	spew.Dump(sets)
	return &sets
}

//
// This is what you call from main()
//
func parseConfig() {
	// first load the config file
	loadConfigFile()

	// override the config file from the command line
	parseFlags()

	log.Println("config.width",	config.Width)
	log.Println("config.height",	config.Height)
	log.Println("config.debug",	config.Debug)

	// check that the config parsing worked
	for key, foo := range config.Accounts {
		log.Println("account =          ", key, foo)
		log.Println("Accounts[key] =    ", config.Accounts[key])
	}
	if (config.Accounts == nil) {
		log.Println("loadConfigFile() config.Accounts == nil")
		log.Println("If debugging is on, should load default config here")
		if (*defaultconfig == true) {
			log.Println("Debugging is on, loading debug config accounts")
			tmp := loadDefaultConfig()
			config.Accounts = tmp.Accounts
			log.Println("loadConfigFile() config.Accounts =", config.Accounts)
		}
	}
}