// Copyright 2016 Open Networking Foundation
//
// 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"
	"io/ioutil"
	"net/url"
	"os"
	"regexp"
	"time"

	maas "github.com/juju/gomaasapi"
)

const (
	appName        = "AUTOMATION"
	maasApiVersion = "2.0"
)

type Config struct {
	PowerHelperUser   string        `default:"cord" envconfig:"POWER_HELPER_USER" desc:"user when integrating with virtual box power mgmt"`
	PowerHelperHost   string        `default:"127.0.0.1" envconfig:"POWER_HELPER_HOST" desc:"virtual box host"`
	PowerHelperScript string        `default:"" envconfig:"POWER_HELPER_SCRIPT" desc:"script for virtual box power mgmt support"`
	ProvisionUrl      string        `default:"" envconfig:"PROVISION_URL" desc:"connection string to connect to provisioner uservice"`
	ProvisionTtl      string        `default:"1h" envconfig:"PROVISION_TTL" desc:"duration to wait for a provisioning request to complete, before considered a failure"`
	LogLevel          string        `default:"warning" envconfig:"LOG_LEVEL" desc:"detail level for logging"`
	LogFormat         string        `default:"text" envconfig:"LOG_FORMAT" desc:"log output format, text or json"`
	ApiKey            string        `envconfig:"MAAS_API_KEY" required:"true" desc:"API key to access MAAS server"`
	ApiKeyFile        string        `default:"/secrets/maas_api_key" envconfig:"MAAS_API_KEY_FILE" desc:"file to hold the secret"`
	ShowApiKey        bool          `default:"false" envconfig:"MAAS_SHOW_API_KEY" desc:"Show API in clear text in logs"`
	MaasUrl           string        `default:"http://localhost/MAAS" envconfig:"MAAS_URL" desc:"URL to access 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("", 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()
var appFlags = flag.NewFlagSet("", flag.ContinueOnError)

func main() {

	config := Config{}
	appFlags.Usage = func() {
		envconfig.Usage(appName, &config)
	}
	if err := appFlags.Parse(os.Args[1:]); err != nil {
		if err != flag.ErrHelp {
			os.Exit(1)
		} else {
			return
		}
	}

	err := envconfig.Process(appName, &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 + "]"
	}

	re := regexp.MustCompile("[^:]")
	pubKey := config.ApiKey
	if !config.ShowApiKey {
		pubKey = re.ReplaceAllString(config.ApiKey, "X")
	}

	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_SHOW_API_KEY:    %t
	    MAAS_API_KEY:         %s
	    MAAS_API_KEY_FILE:    %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.ShowApiKey,
		pubKey, config.ApiKeyFile, config.QueryInterval,
		filterPrefix+string(filterAsJson), mappingsPrefix+string(mappingsAsJson),
		config.PreviewOnly, config.AlwaysRename,
		config.LogLevel, config.LogFormat)

	// Attempt to load the API key from a file if it was not set via the environment
	// and if the file exists
	if config.ApiKey == "" {
		log.Debugf("Attempting to read MAAS API key from file '%s', because it was not set via environment", config.ApiKeyFile)
		keyBytes, err := ioutil.ReadFile(config.ApiKeyFile)
		if err != nil {
			log.Warnf("Failed to read MAAS API key from file '%s', was the file mounted as a volume? : %s ",
				config.ApiKeyFile, err)
		} else {
			config.ApiKey = string(keyBytes)
			if config.ShowApiKey {
				pubKey = config.ApiKey
			} else {
				pubKey = re.ReplaceAllString(config.ApiKey, "X")
			}
		}
	}

	authClient, err := maas.NewAuthenticatedClient(config.MaasUrl, config.ApiKey, maasApiVersion)
	checkError(err, "Unable to use specified client key, '%s', to authenticate to the MAAS server: %s",
		pubKey, 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)
		}
	}
}
