// Copyright 2016 Open Networking Laboratory
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main

import (
	"encoding/json"
	"flag"
	"github.com/Sirupsen/logrus"
	"github.com/kelseyhightower/envconfig"
	"net/url"
	"os"
	"time"

	maas "github.com/juju/gomaasapi"
)

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"`
	LogLevel          string        `default:"warning" envconfig:"LOG_LEVEL"`
	LogFormat         string        `default:"text" envconfig:"LOG_FORMAT"`
	ApiKey            string        `envconfig:"MAAS_API_KEY" required:"true" desc:"API key to access MAAS server"`
	MaasUrl           string        `default:"http://localhost/MAAS" envconfig:"MAAS_URL" desc:"URL to access MAAS server"`
	ApiVersion        string        `default:"1.0" envconfig:"MAAS_API_VERSION" desc:"API version to use with MAAS server"`
	QueryInterval     time.Duration `default:"15s" envconfig:"MAAS_QUERY_INTERVAL" desc:"frequency to query MAAS service for nodes"`
	PreviewOnly       bool          `default:"false" envconfig:"PREVIEW_ONLY" desc:"display actions that would be taken, but don't execute them"`
	AlwaysRename      bool          `default:"true" envconfig:"ALWAYS_RENAME" desc:"attempt to rename hosts at every stage or workflow"`
	Mappings          string        `default:"{}" envconfig:"MAC_TO_NAME_MAPPINGS" desc:"custom MAC address to host name mappings"`
	FilterSpec        string        `default:"{\"hosts\":{\"include\":[\".*\"]},\"zones\":{\"include\":[\"default\"]}}" envconfig:"HOST_FILTER_SPEC" desc:"constrain hosts that are 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(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.Warningf(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
}

var log = logrus.New()

func main() {

	flag.Parse()
	config := Config{}
	err := envconfig.Process("AUTOMATION", &config)
	if err != nil {
		log.Fatalf("Unable to parse configuration options : %s", err)
	}

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

	switch config.LogFormat {
	case "json":
		log.Formatter = &logrus.JSONFormatter{}
	default:
		log.Formatter = &logrus.TextFormatter{
			FullTimestamp: true,
			ForceColors:   true,
		}
	}

	level, err := logrus.ParseLevel(config.LogLevel)
	if err != nil {
		level = logrus.WarnLevel
	}
	log.Level = level

	options.ProvisionTTL, err = time.ParseDuration(config.ProvisionTtl)
	checkError(err, "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(config.FilterSpec) > 0 {
		if config.FilterSpec[0] == '@' {
			name := os.ExpandEnv((config.FilterSpec)[1:])
			file, err := os.OpenFile(name, os.O_RDONLY, 0)
			checkError(err, "unable to open file '%s' to load the filter : %s", name, err)
			decoder := json.NewDecoder(file)
			err = decoder.Decode(&options.Filter)
			checkError(err, "unable to parse filter configuration from file '%s' : %s", name, err)
		} else {
			err := json.Unmarshal([]byte(config.FilterSpec), &options.Filter)
			checkError(err, "unable to parse filter specification: '%s' : %s", config.FilterSpec, 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(config.Mappings) > 0 {
		if config.Mappings[0] == '@' {
			name := os.ExpandEnv(config.Mappings[1:])
			file, err := os.OpenFile(name, os.O_RDONLY, 0)
			checkError(err, "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, "unable to parse filter configuration from file '%s' : %s", name, err)
		} else {
			err := json.Unmarshal([]byte(config.Mappings), &options.Mappings)
			checkError(err, "unable to parse mac name mapping: '%s' : %s", config.Mappings, err)
		}
	}

	// Get human readable strings for config output
	mappingsAsJson, err := json.Marshal(options.Mappings)
	checkError(err, "Unable to marshal MAC to hostname mappings to JSON : %s", err)
	mappingsPrefix := ""

	if len(config.Mappings) > 0 && config.Mappings[0] == '@' {
		mappingsPrefix = "[" + config.Mappings + "]"
	}

	filterAsJson, err := json.Marshal(options.Filter)
	checkError(err, "Unable to marshal host filter to JSON : %s", err)
	filterPrefix := ""
	if len(config.FilterSpec) > 0 && config.FilterSpec[0] == '@' {
		filterPrefix = "[" + config.FilterSpec + "]"
	}

	log.Infof(`Configuration:
            POWER_HELPER_USER:   %s
	    POWER_HELPER_HOST:   %s
	    POWER_HELPER_SCRIPT: %s
	    PROVISION_URL:       %s
	    PROVISION_TTL:       %s
	    MAAS_URL:            %s
	    MAAS_API_KEY:        %s
	    MAAS_API_VERSION:    %s
	    MAAS_QUERY_INTERVAL: %s
	    HOST_FILTER_SPEC:    %+v
	    MAC_TO_NAME_MAPPINGS:%+v
	    PREVIEW_ONLY:        %t
	    ALWAYS_RENAME:       %t
	    LOG_LEVEL:           %s
	    LOG_FORMAT:		 %s`,
		config.PowerHelperUser, config.PowerHelperHost, config.PowerHelperScript,
		config.ProvisionUrl, config.ProvisionTtl,
		config.MaasUrl, config.ApiKey, config.ApiVersion, config.QueryInterval,
		filterPrefix+string(filterAsJson), mappingsPrefix+string(mappingsAsJson),
		config.PreviewOnly, config.AlwaysRename,
		config.LogLevel, config.LogFormat)

	authClient, err := maas.NewAuthenticatedClient(config.MaasUrl, config.ApiKey, config.ApiVersion)
	checkError(err, "Unable to use specified client key, '%s', to authenticate to the MAAS server: %s",
		config.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 !(config.PreviewOnly) {
		// Create a ticker and fetch and process the nodes every "period"
		for {
			log.Infof("query server at %s", time.Now())
			nodes, _ := fetchNodes(client)
			ProcessAll(client, nodes, options)

			// Sleep for the Interval and then process again.
			time.Sleep(config.QueryInterval)
		}
	}
}
