package main

import (
	"encoding/binary"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"net"
	"os"
)

func main() {

	shutdownPtr := flag.Bool("shutdown", false, "Shutdown server")
	suspendPtr := flag.String("suspend", "", "Instance to Suspend")
	resumePtr := flag.String("resume", "", "Instance to Resume")
	addPtr := flag.String("add", "", "Instance to add")
	statusPtr := flag.Bool("status", false, "Check status")
	flag.Parse()

	/* Condition verification */
	totalflags := 0
	var commandMap CommandMap
	var responseback ResponseBack

	if *shutdownPtr {
		totalflags++
		commandMap.Type = "shutdown"
	}
	if *statusPtr {
		totalflags++
		commandMap.Type = "status"
	}
	if *addPtr != "" {
		totalflags++
		commandMap.Type = "add"
		commandMap.Endpoint = *addPtr
	}
	if *suspendPtr != "" {
		totalflags++
		commandMap.Type = "suspend"
	}
	if *resumePtr != "" {
		totalflags++
		commandMap.Type = "resume"
	}
	if totalflags > 1 {
		fmt.Println("Incompatible arguments, exiting.")
		os.Exit(1)
	} else if totalflags == 0 {
		fmt.Println("No options specified, exiting.")
		os.Exit(1)
	}

	commandByte, err := json.Marshal(commandMap)
	if err != nil {
		fmt.Println(err)
		return
	}
	c, err := net.Dial("tcp", "127.0.0.1:5555")
	if err != nil {
		fmt.Println(err)
		return
	}
	sizebytes := make([]byte, 4)
	b := len(commandByte)

	// Send the request
	binary.LittleEndian.PutUint32(sizebytes, uint32(b))
	_, err = c.Write(sizebytes)
	if err != nil {
		fmt.Println(err)
		return
	}
	_, err = c.Write(commandByte)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Read the response
	n, err := io.ReadFull(c, sizebytes)
	if err != nil || n != 4 {
		fmt.Println("err", err, n)
	}
	jsonsize := int(binary.LittleEndian.Uint32(sizebytes))
	responsebytes := make([]byte, jsonsize)
	_, err = io.ReadFull(c, responsebytes)
	if err != nil {
		fmt.Println("Read Error", err)
	}
	err = json.Unmarshal(responsebytes, &responseback)
	if err != nil {
		fmt.Println("Unmarshal error", err)
	}

	switch commandMap.Type {
	case "add":
		fmt.Println(responseback.Message)
	case "status":
		fmt.Println("Status\t\tLastRun\t\t\tCaptureType\tEndpoint")
		for endpoint, runninginstance := range responseback.RunningInstances {
			if runninginstance.Status == 0 {
				fmt.Fprintf(os.Stdout, "New\t")
				fmt.Fprintf(os.Stdout, "\tNever\t\t\t")
			} else if runninginstance.Status == 200 {
				fmt.Fprintf(os.Stdout, "Running\t")
				fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
			} else if runninginstance.Status == 429 {
				fmt.Fprintf(os.Stdout, "TooManyRequests\t")
				fmt.Fprintf(os.Stdout, "%s\t", runninginstance.LastRun)
			} else if runninginstance.Status == 600 {
				fmt.Fprintf(os.Stdout, "ClientIssue")
				fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
			} else if runninginstance.Status == 602 {
				fmt.Fprintf(os.Stdout, "BadInstance")
				fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
			} else if runninginstance.Status == 605 {
				fmt.Fprintf(os.Stdout, "UnsupportedNode")
				fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
			} else {
				fmt.Fprintf(os.Stdout, "%d\t", runninginstance.Status)
				fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
			}
			if runninginstance.LastRun == "Queued" {
				fmt.Fprintf(os.Stdout, "\t\t")
			}
			fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.CaptureType)
			fmt.Fprintf(os.Stdout, "%s\n", endpoint)
		}
	}
}