package main

import (
	"encoding/json"
	"flag"
	"github.com/kelseyhightower/envconfig"
	"log"
	"net/url"
	"os"
	"strings"
	"time"
	"unicode"

	maas "github.com/juju/gomaasapi"
)

const (
	// defaultFilter specifies the default filter to use when none is specified
	defaultFilter = `{
	  "hosts" : {
	    "include" : [ ".*" ],
		"exclude" : []
	  },
	  "zones" : {
	    "include" : ["default"],
		"exclude" : []
           }
	}`
	defaultMapping = "{}"
)

type Config struct {
	PowerHelperUser   string `default:"cord" envconfig:"POWER_HELPER_USER"`
	PowerHelperHost   string `default:"127.0.0.1" envconfig:"POWER_HELPER_HOST"`
	PowerHelperScript string `default:"" envconfig:"POWER_HELPER_SCRIPT"`
	ProvisionUrl      string `default:"" envconfig:"PROVISION_URL"`
	ProvisionTtl      string `default:"1h" envconfig:"PROVISION_TTL"`
}

var apiKey = flag.String("apikey", "", "key with which to access MAAS server")
var maasURL = flag.String("maas", "http://localhost/MAAS", "url over which to access MAAS")
var apiVersion = flag.String("apiVersion", "1.0", "version of the API to access")
var queryPeriod = flag.String("period", "15s", "frequency the MAAS service is polled for node states")
var preview = flag.Bool("preview", false, "displays the action that would be taken, but does not do the action, in this mode the nodes are processed only once")
var mappings = flag.String("mappings", "{}", "the mac to name mappings")
var always = flag.Bool("always-rename", true, "attempt to rename at every stage of workflow")
var verbose = flag.Bool("verbose", false, "display verbose logging")
var filterSpec = flag.String("filter", strings.Map(func(r rune) rune {
	if unicode.IsSpace(r) {
		return -1
	}
	return r
}, defaultFilter), "constrain by hostname what will be automated")

// checkError if the given err is not nil, then fatally log the message, else
// return false.
func checkError(err error, message string, v ...interface{}) bool {
	if err != nil {
		log.Fatalf("[error] "+message, v)
	}
	return false
}

// checkWarn if the given err is not nil, then log the message as a warning and
// return true, else return false.
func checkWarn(err error, message string, v ...interface{}) bool {
	if err != nil {
		log.Printf("[warn] "+message, v)
		return true
	}
	return false
}

// fetchNodes do a HTTP GET to the MAAS server to query all the nodes
func fetchNodes(client *maas.MAASObject) ([]MaasNode, error) {
	nodeListing := client.GetSubObject("nodes")
	listNodeObjects, err := nodeListing.CallGet("list", url.Values{})
	if checkWarn(err, "unable to get the list of all nodes: %s", err) {
		return nil, err
	}
	listNodes, err := listNodeObjects.GetArray()
	if checkWarn(err, "unable to get the node objects for the list: %s", err) {
		return nil, err
	}

	var nodes = make([]MaasNode, len(listNodes))
	for index, nodeObj := range listNodes {
		node, err := nodeObj.GetMAASObject()
		if !checkWarn(err, "unable to retrieve object for node: %s", err) {
			nodes[index] = MaasNode{node}
		}
	}
	return nodes, nil
}

func main() {

	flag.Parse()
	config := Config{}
	err := envconfig.Process("AUTOMATION", &config)
	checkError(err, "[error] unable to parse environment options : %s", err)

	options := ProcessingOptions{
		Preview:         *preview,
		Verbose:         *verbose,
		AlwaysRename:    *always,
		Provisioner:     NewProvisioner(&ProvisionerConfig{Url: config.ProvisionUrl}),
		ProvisionURL:    config.ProvisionUrl,
		PowerHelper:     config.PowerHelperScript,
		PowerHelperUser: config.PowerHelperUser,
		PowerHelperHost: config.PowerHelperHost,
	}

	options.ProvisionTTL, err = time.ParseDuration(config.ProvisionTtl)
	checkError(err, "[error] unable to parse specified duration of '%s' : %s", err)

	// Determine the filter, this can either be specified on the the command
	// line as a value or a file reference. If none is specified the default
	// will be used
	if len(*filterSpec) > 0 {
		if (*filterSpec)[0] == '@' {
			name := os.ExpandEnv((*filterSpec)[1:])
			file, err := os.OpenFile(name, os.O_RDONLY, 0)
			checkError(err, "[error] unable to open file '%s' to load the filter : %s", name, err)
			decoder := json.NewDecoder(file)
			err = decoder.Decode(&options.Filter)
			checkError(err, "[error] unable to parse filter configuration from file '%s' : %s", name, err)
		} else {
			err := json.Unmarshal([]byte(*filterSpec), &options.Filter)
			checkError(err, "[error] unable to parse filter specification: '%s' : %s", *filterSpec, err)
		}
	} else {
		err := json.Unmarshal([]byte(defaultFilter), &options.Filter)
		checkError(err, "[error] unable to parse default filter specificiation: '%s' : %s", defaultFilter, err)
	}

	// Determine the mac to name mapping, this can either be specified on the the command
	// line as a value or a file reference. If none is specified the default
	// will be used
	if len(*mappings) > 0 {
		if (*mappings)[0] == '@' {
			name := os.ExpandEnv((*mappings)[1:])
			file, err := os.OpenFile(name, os.O_RDONLY, 0)
			checkError(err, "[error] unable to open file '%s' to load the mac name mapping : %s", name, err)
			decoder := json.NewDecoder(file)
			err = decoder.Decode(&options.Mappings)
			checkError(err, "[error] unable to parse filter configuration from file '%s' : %s", name, err)
		} else {
			err := json.Unmarshal([]byte(*mappings), &options.Mappings)
			checkError(err, "[error] unable to parse mac name mapping: '%s' : %s", *mappings, err)
		}
	} else {
		err := json.Unmarshal([]byte(defaultMapping), &options.Mappings)
		checkError(err, "[error] unable to parse default mac name mappings: '%s' : %s", defaultMapping, err)
	}

	// Verify the specified period for queries can be converted into a Go duration
	period, err := time.ParseDuration(*queryPeriod)
	checkError(err, "[error] unable to parse specified query period duration: '%s': %s", queryPeriod, err)

	log.Printf(`Configuration:
	    MAAS URL:            %s
	    MAAS API Version:    %s
	    MAAS Query Interval: %s
	    Node Filter:         %s
	    Node Name Mappings:  %s
	    Preview:             %v
	    Verbose:             %v
	    Always Rename:       %v
	    Provision URL:       %s
	    Provision TTL:       %s
	    Power Helper:        %s
	    Power Helper User:   %s
	    Power Helper Host:   %s`,
		*maasURL, *apiVersion, *queryPeriod, *filterSpec, *mappings, options.Preview,
		options.Verbose, options.AlwaysRename, options.ProvisionURL, options.ProvisionTTL,
		options.PowerHelper, options.PowerHelperUser, options.PowerHelperHost)

	authClient, err := maas.NewAuthenticatedClient(*maasURL, *apiKey, *apiVersion)
	if err != nil {
		checkError(err, "[error] Unable to use specified client key, '%s', to authenticate to the MAAS server: %s", *apiKey, err)
	}

	// Create an object through which we will communicate with MAAS
	client := maas.NewMAAS(*authClient)

	// This utility essentially polls the MAAS server for node state and
	// process the node to the next state. This is done by kicking off the
	// process every specified duration. This means that the first processing of
	// nodes will have "period" in the future. This is really not the behavior
	// we want, we really want, do it now, and then do the next one in "period".
	// So, the code does one now.
	nodes, _ := fetchNodes(client)
	ProcessAll(client, nodes, options)

	if !(*preview) {
		// Create a ticker and fetch and process the nodes every "period"
		ticker := time.NewTicker(period)
		for t := range ticker.C {
			log.Printf("[info] query server at %s", t)
			nodes, _ := fetchNodes(client)
			ProcessAll(client, nodes, options)
		}
	}
}
