package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
	"time"

	maas "github.com/juju/gomaasapi"
)

// Action how to get from there to here
type Action func(*maas.MAASObject, MaasNode, ProcessingOptions) error

// Transition the map from where i want to be from where i might be
type Transition struct {
	Target  string
	Current string
	Using   Action
}

type Power struct {
	Name          string `json:"name"`
	MacAddress    string `json:"mac_address"`
	PowerPassword string `json:"power_password"`
	PowerAddress  string `json:"power_address"`
}

// ProcessingOptions used to determine on what hosts to operate
type ProcessingOptions struct {
	Filter struct {
		Zones struct {
			Include []string
			Exclude []string
		}
		Hosts struct {
			Include []string
			Exclude []string
		}
	}
	Mappings        map[string]interface{}
	Verbose         bool
	Preview         bool
	AlwaysRename    bool
	ProvTracker     Tracker
	ProvisionURL    string
	ProvisionTTL    time.Duration
	PowerHelper     string
	PowerHelperUser string
	PowerHelperHost string
}

// Transitions the actual map
//
// Currently this is a hand compiled / optimized "next step" table. This should
// really be generated from the state machine chart input. Once this has been
// accomplished you should be able to determine the action to take given your
// target state and your current state.
var Transitions = map[string]map[string][]Action{
	"Deployed": {
		"New":                 []Action{Reset, Commission},
		"Deployed":            []Action{Provision, Done},
		"Ready":               []Action{Reset, Aquire},
		"Allocated":           []Action{Reset, Deploy},
		"Retired":             []Action{Reset, AdminState},
		"Reserved":            []Action{Reset, AdminState},
		"Releasing":           []Action{Reset, Wait},
		"DiskErasing":         []Action{Reset, Wait},
		"Deploying":           []Action{Reset, Wait},
		"Commissioning":       []Action{Reset, Wait},
		"Missing":             []Action{Reset, Fail},
		"FailedReleasing":     []Action{Reset, Fail},
		"FailedDiskErasing":   []Action{Reset, Fail},
		"FailedDeployment":    []Action{Reset, Fail},
		"Broken":              []Action{Reset, Fail},
		"FailedCommissioning": []Action{Reset, Fail},
	},
}

const (
	// defaultStateMachine Would be nice to drive from a graph language
	defaultStateMachine string = `
	(New)->(Commissioning)
        (Commissioning)->(FailedCommissioning)
        (FailedCommissioning)->(New)
        (Commissioning)->(Ready)
        (Ready)->(Deploying)
        (Ready)->(Allocated)
        (Allocated)->(Deploying)
        (Deploying)->(Deployed)
        (Deploying)->(FailedDeployment)
        (FailedDeployment)->(Broken)
        (Deployed)->(Releasing)
        (Releasing)->(FailedReleasing)
        (FailedReleasing)->(Broken)
        (Releasing)->(DiskErasing)
        (DiskErasing)->(FailedEraseDisk)
        (FailedEraseDisk)->(Broken)
        (Releasing)->(Ready)
        (DiskErasing)->(Ready)
        (Broken)->(Ready)
        (Deployed)->(Provisioning)
	(Provisioning)->|a|
	|a|->(Execute Script)->|b|
	|a|->(HTTP PUT)
	(HTTP PUT)->(HTTP GET)
	(HTTP GET)->(HTTP GET)
	(HTTP GET)->|b|
	|b|->(Provisioned)
	|b|->(ProvisionError)
        (ProvisionError)->(Provisioning)`
)

// updateName - changes the name of the MAAS node based on the configuration file
func updateNodeName(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	macs := node.MACs()

	// Get current node name and strip off domain name
	current := node.Hostname()
	if i := strings.IndexRune(current, '.'); i != -1 {
		current = current[:i]
	}
	for _, mac := range macs {
		if entry, ok := options.Mappings[mac]; ok {
			if name, ok := entry.(map[string]interface{})["hostname"]; ok && current != name.(string) {
				nodesObj := client.GetSubObject("nodes")
				nodeObj := nodesObj.GetSubObject(node.ID())
				log.Printf("RENAME '%s' to '%s'\n", node.Hostname(), name.(string))

				if !options.Preview {
					nodeObj.Update(url.Values{"hostname": []string{name.(string)}})
				}
			}
		}
	}
	return nil
}

// Reset we are at the target state, nothing to do
var Reset = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	if options.Verbose {
		log.Printf("RESET: %s", node.Hostname())
	}

	if options.AlwaysRename {
		updateNodeName(client, node, options)
	}

	options.ProvTracker.Clear(node.ID())

	return nil
}

// Provision we are at the target state, nothing to do
var Provision = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	if options.Verbose {
		log.Printf("CHECK PROVISION: %s", node.Hostname())
	}

	if options.AlwaysRename {
		updateNodeName(client, node, options)
	}

	record, err := options.ProvTracker.Get(node.ID())
	if options.Verbose {
		log.Printf("[info] Current state of node '%s' is '%s'", node.Hostname(), record.State.String())
	}
	if err != nil {
		log.Printf("[warn] unable to retrieve provisioning state of node '%s' : %s", node.Hostname(), err)
	} else if record.State == Unprovisioned || record.State == ProvisionError {
		var err error = nil
		var callout *url.URL
		log.Printf("PROVISION '%s'", node.Hostname())
		if len(options.ProvisionURL) > 0 {
			if options.Verbose {
				log.Printf("[info] Provisioning callout to '%s'", options.ProvisionURL)
			}
			callout, err = url.Parse(options.ProvisionURL)
			if err != nil {
				log.Printf("[error] Failed to parse provisioning URL '%s' : %s", options.ProvisionURL, err)
			} else {
				ips := node.IPs()
				ip := ""
				if len(ips) > 0 {
					ip = ips[0]
				}
				macs := node.MACs()
				mac := ""
				if len(macs) > 0 {
					mac = macs[0]
				}
				switch callout.Scheme {
				// If the scheme is a file, then we will execute the refereced file
				case "", "file":
					if options.Verbose {
						log.Printf("[info] executing local script file '%s'", callout.Path)
					}
					record.State = Provisioning
					record.Timestamp = time.Now().Unix()
					options.ProvTracker.Set(node.ID(), record)
					err = exec.Command(callout.Path, node.ID(), node.Hostname(), ip, mac).Run()
					if err != nil {
						log.Printf("[error] Failed to execute '%s' : %s", options.ProvisionURL, err)
					} else {
						if options.Verbose {
							log.Printf("[info] Marking node '%s' with ID '%s' as provisioned",
								node.Hostname(), node.ID())
						}
						record.State = Provisioned
						options.ProvTracker.Set(node.ID(), record)
					}

				default:
					if options.Verbose {
						log.Printf("[info] POSTing to '%s'", options.ProvisionURL)
					}
					data := map[string]string{
						"id":   node.ID(),
						"name": node.Hostname(),
						"ip":   ip,
						"mac":  mac,
					}
					hc := http.Client{}
					var b []byte
					b, err = json.Marshal(data)
					if err != nil {
						log.Printf("[error] Unable to marshal node data : %s", err)
					} else {
						var req *http.Request
						var resp *http.Response
						if options.Verbose {
							log.Printf("[debug] POSTing data '%s'", string(b))
						}
						req, err = http.NewRequest("POST", options.ProvisionURL, bytes.NewReader(b))
						if err != nil {
							log.Printf("[error] Unable to construct POST request to provisioner : %s",
								err)
						} else {
							req.Header.Add("Content-Type", "application/json")
							resp, err = hc.Do(req)
							if err != nil {
								log.Printf("[error] Unable to process POST request : %s",
									err)
							} else {
								defer resp.Body.Close()
								if resp.StatusCode == http.StatusAccepted {
									record.State = Provisioning
								} else {
									record.State = ProvisionError
								}
								record.Timestamp = time.Now().Unix()
								options.ProvTracker.Set(node.ID(), record)
							}
						}
					}
				}
			}
		}

		if err != nil {
			if options.Verbose {
				log.Printf("[warn] Not marking node '%s' with ID '%s' as provisioned, because of error '%s'",
					node.Hostname(), node.ID(), err)
				record.State = ProvisionError
				options.ProvTracker.Set(node.ID(), record)
			}
		}
	} else if record.State == Provisioning && time.Since(time.Unix(record.Timestamp, 0)) > options.ProvisionTTL {
		log.Printf("[error] Provisioning of node '%s' has passed provisioning TTL of '%v'",
			node.Hostname(), options.ProvisionTTL)
		record.State = ProvisionError
		options.ProvTracker.Set(node.ID(), record)
	} else if record.State == Provisioning {
		callout, err := url.Parse(options.ProvisionURL)
		if err != nil {
			log.Printf("[error] Unable to parse provisioning URL '%s' : %s", options.ProvisionURL, err)
		} else if callout.Scheme != "file" {
			var req *http.Request
			var resp *http.Response
			if options.Verbose {
				log.Printf("[info] Fetching provisioning state for node '%s'", node.Hostname())
			}
			req, err = http.NewRequest("GET", options.ProvisionURL+"/"+node.ID(), nil)
			if err != nil {
				log.Printf("[error] Unable to construct GET request to provisioner : %s", err)
			} else {
				hc := http.Client{}
				resp, err = hc.Do(req)
				if err != nil {
					log.Printf("[error] Failed to quest provision state for node '%s' : %s",
						node.Hostname(), err)
				} else {
					switch resp.StatusCode {
					case http.StatusOK: // provisioning completed
						if options.Verbose {
							log.Printf("[info] Marking node '%s' with ID '%s' as provisioned",
								node.Hostname(), node.ID())
						}
						record.State = Provisioned
						options.ProvTracker.Set(node.ID(), record)
					case http.StatusAccepted: // in the provisioning state
						// Noop, presumably alread in this state
					default: // Consider anything else an erorr
						log.Printf("[warn] Node '%s' with ID '%s' failed provisioning, will retry",
							node.Hostname(), node.ID())
						record.State = ProvisionError
						options.ProvTracker.Set(node.ID(), record)
					}
				}
			}
		}
	} else if options.Verbose {
		log.Printf("[info] Not invoking provisioning for '%s', currned state is '%s'", node.Hostname(),
			record.State.String())
	}

	return nil
}

// Done we are at the target state, nothing to do
var Done = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	// As devices are normally in the "COMPLETED" state we don't want to
	// log this fact unless we are in verbose mode. I suspect it would be
	// nice to log it once when the device transitions from a non COMPLETE
	// state to a complete state, but that would require keeping state.
	if options.Verbose {
		log.Printf("COMPLETE: %s", node.Hostname())
	}

	if options.AlwaysRename {
		updateNodeName(client, node, options)
	}

	return nil
}

// Deploy cause a node to deploy
var Deploy = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	log.Printf("DEPLOY: %s", node.Hostname())

	if options.AlwaysRename {
		updateNodeName(client, node, options)
	}

	if !options.Preview {
		nodesObj := client.GetSubObject("nodes")
		myNode := nodesObj.GetSubObject(node.ID())
		// Start the node with the trusty distro. This should really be looked up or
		// a parameter default
		_, err := myNode.CallPost("start", url.Values{"distro_series": []string{"trusty"}})
		if err != nil {
			log.Printf("ERROR: DEPLOY '%s' : '%s'", node.Hostname(), err)
			return err
		}
	}
	return nil
}

// Aquire aquire a machine to a specific operator
var Aquire = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	log.Printf("AQUIRE: %s", node.Hostname())
	nodesObj := client.GetSubObject("nodes")

	if options.AlwaysRename {
		updateNodeName(client, node, options)
	}

	if !options.Preview {
		// With a new version of MAAS we have to make sure the node is linked
		// to the subnet vid DHCP before we move to the Aquire state. To do this
		// We need to unlink the interface to the subnet and then relink it.
		//
		// Iterate through all the interfaces on the node, searching for ones
		// that are valid and not DHCP and move them to DHCP
		ifcsObj := client.GetSubObject("nodes").GetSubObject(node.ID()).GetSubObject("interfaces")
		ifcsListObj, err := ifcsObj.CallGet("", url.Values{})
		if err != nil {
			return err
		}

		ifcsArray, err := ifcsListObj.GetArray()
		if err != nil {
			return err
		}

		for _, ifc := range ifcsArray {
			ifcMap, err := ifc.GetMap()
			if err != nil {
				return err
			}

			// Iterate over the links assocated with the interface, looking for
			// links with a subnect as well as a mode of "auto"
			links, ok := ifcMap["links"]
			if ok {
				linkArray, err := links.GetArray()
				if err != nil {
					return err
				}

				for _, link := range linkArray {
					linkMap, err := link.GetMap()
					if err != nil {
						return err
					}
					subnet, ok := linkMap["subnet"]
					if ok {
						subnetMap, err := subnet.GetMap()
						if err != nil {
							return err
						}

						val, err := linkMap["mode"].GetString()
						if err != nil {
							return err
						}

						if val == "auto" {
							// Found one we like, so grab the subnet from the data and
							// then relink this as DHCP
							cidr, err := subnetMap["cidr"].GetString()
							if err != nil {
								return err
							}

							fifcID, err := ifcMap["id"].GetFloat64()
							if err != nil {
								return err
							}
							ifcID := strconv.Itoa(int(fifcID))

							flID, err := linkMap["id"].GetFloat64()
							if err != nil {
								return err
							}
							lID := strconv.Itoa(int(flID))

							ifcObj := ifcsObj.GetSubObject(ifcID)
							_, err = ifcObj.CallPost("unlink_subnet", url.Values{"id": []string{lID}})
							if err != nil {
								return err
							}
							_, err = ifcObj.CallPost("link_subnet", url.Values{"mode": []string{"DHCP"}, "subnet": []string{cidr}})
							if err != nil {
								return err
							}
						}
					}
				}
			}
		}
		_, err = nodesObj.CallPost("acquire",
			url.Values{"name": []string{node.Hostname()}})
		if err != nil {
			log.Printf("ERROR: AQUIRE '%s' : '%s'", node.Hostname(), err)
			return err
		}
	}
	return nil
}

// Commission cause a node to be commissioned
var Commission = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	updateNodeName(client, node, options)

	// Need to understand the power state of the node. We only want to move to "Commissioning" if the node
	// power is off. If the node power is not off, then turn it off.
	state := node.PowerState()
	switch state {
	case "on":
		// Attempt to turn the node off
		log.Printf("POWER DOWN: %s", node.Hostname())
		if !options.Preview {
			//POST /api/1.0/nodes/{system_id}/ op=stop
			nodesObj := client.GetSubObject("nodes")
			nodeObj := nodesObj.GetSubObject(node.ID())
			_, err := nodeObj.CallPost("stop", url.Values{"stop_mode": []string{"soft"}})
			if err != nil {
				log.Printf("ERROR: Commission '%s' : changing power start to off : '%s'", node.Hostname(), err)
			}
			return err
		}
		break
	case "off":
		// We are off so move to commissioning
		log.Printf("COMISSION: %s", node.Hostname())
		if !options.Preview {
			nodesObj := client.GetSubObject("nodes")
			nodeObj := nodesObj.GetSubObject(node.ID())

			updateNodeName(client, node, options)

			_, err := nodeObj.CallPost("commission", url.Values{})
			if err != nil {
				log.Printf("ERROR: Commission '%s' : '%s'", node.Hostname(), err)
			}
			return err
		}
		break
	default:
		// We are in a state from which we can't move forward.
		log.Printf("[warn]: %s has invalid power state '%s'", node.Hostname(), state)

		// If a power helper script is set, we have an unknown power state, and
		// we have not power type then attempt to use the helper script to discover
		// and set the power settings
		if options.PowerHelper != "" && node.PowerType() == "" {
			cmd := exec.Command(options.PowerHelper,
				append([]string{options.PowerHelperUser, options.PowerHelperHost},
					node.MACs()...)...)
			stdout, err := cmd.Output()
			if err != nil {
				log.Printf("[error] Failed while executing power helper script '%s' : %s",
					options.PowerHelper, err)
				return err
			}
			power := Power{}
			err = json.Unmarshal(stdout, &power)
			if err != nil {
				log.Printf("[error] Failed to parse output of power helper script '%s' : %s",
					options.PowerHelper, err)
				return err
			}
			switch power.Name {
			case "amt":
				params := map[string]string{
					"mac_address":   power.MacAddress,
					"power_pass":    power.PowerPassword,
					"power_address": power.PowerAddress,
				}
				node.UpdatePowerParameters(power.Name, params)
			default:
				log.Printf("[warn] Unsupported power type discovered '%s'", power.Name)
			}
		}
		break
	}
	return nil
}

// Wait a do nothing state, while work is being done
var Wait = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	log.Printf("WAIT: %s", node.Hostname())
	return nil
}

// Fail a state from which we cannot, currently, automatically recover
var Fail = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	log.Printf("FAIL: %s", node.Hostname())
	return nil
}

// AdminState an administrative state from which we should make no automatic transition
var AdminState = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	log.Printf("ADMIN: %s", node.Hostname())
	return nil
}

func findActions(target string, current string) ([]Action, error) {
	targets, ok := Transitions[target]
	if !ok {
		log.Printf("[warn] unable to find transitions to target state '%s'", target)
		return nil, fmt.Errorf("Could not find transition to target state '%s'", target)
	}

	actions, ok := targets[current]
	if !ok {
		log.Printf("[warn] unable to find transition from current state '%s' to target state '%s'",
			current, target)
		return nil, fmt.Errorf("Could not find transition from current state '%s' to target state '%s'",
			current, target)
	}

	return actions, nil
}

// ProcessActions
func ProcessActions(actions []Action, client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	var err error
	for _, action := range actions {
		if err = action(client, node, options); err != nil {
			log.Printf("[error] Error while processing action for node '%s' : %s",
				node.Hostname(), err)
			break
		}
	}
	return err
}

// ProcessNode something
func ProcessNode(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
	substatus, err := node.GetInteger("substatus")
	if err != nil {
		return err
	}
	actions, err := findActions("Deployed", MaasNodeStatus(substatus).String())
	if err != nil {
		return err
	}

	if options.Preview {
		ProcessActions(actions, client, node, options)
	} else {
		go ProcessActions(actions, client, node, options)
	}
	return nil
}

func buildFilter(filter []string) ([]*regexp.Regexp, error) {

	results := make([]*regexp.Regexp, len(filter))
	for i, v := range filter {
		r, err := regexp.Compile(v)
		if err != nil {
			return nil, err
		}
		results[i] = r
	}
	return results, nil
}

func matchedFilter(include []*regexp.Regexp, target string) bool {
	for _, e := range include {
		if e.MatchString(target) {
			return true
		}
	}
	return false
}

// ProcessAll something
func ProcessAll(client *maas.MAASObject, nodes []MaasNode, options ProcessingOptions) []error {
	errors := make([]error, len(nodes))
	includeHosts, err := buildFilter(options.Filter.Hosts.Include)
	if err != nil {
		log.Fatalf("[error] invalid regular expression for include filter '%s' : %s", options.Filter.Hosts.Include, err)
	}

	includeZones, err := buildFilter(options.Filter.Zones.Include)
	if err != nil {
		log.Fatalf("[error] invalid regular expression for include filter '%v' : %s", options.Filter.Zones.Include, err)
	}

	for i, node := range nodes {
		// For hostnames we always match on an empty filter
		if len(includeHosts) >= 0 && matchedFilter(includeHosts, node.Hostname()) {

			// For zones we don't match on an empty filter
			if len(includeZones) >= 0 && matchedFilter(includeZones, node.Zone()) {
				err := ProcessNode(client, node, options)
				if err != nil {
					errors[i] = err
				} else {
					errors[i] = nil
				}
			} else {
				if options.Verbose {
					log.Printf("[info] ignoring node '%s' as its zone '%s' didn't match include zone name filter '%v'",
						node.Hostname(), node.Zone(), options.Filter.Zones.Include)
				}
			}
		} else {
			if options.Verbose {
				log.Printf("[info] ignoring node '%s' as it didn't match include hostname filter '%v'",
					node.Hostname(), options.Filter.Hosts.Include)
			}
		}
	}
	return errors
}
