package main

/*
   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.
*/

import (
	"compress/gzip"
	"encoding/base64"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/apache/trafficcontrol/lib/go-tc"
	to "github.com/apache/trafficcontrol/traffic_ops/v3-client"

	"github.com/apache/trafficcontrol/grove/config"
	"github.com/apache/trafficcontrol/grove/remap"
	"github.com/apache/trafficcontrol/grove/remapdata"
	"github.com/apache/trafficcontrol/grove/web"
)

const Version = "0.2"
const UserAgent = "grove-tc-cfg/" + Version
const TrafficOpsTimeout = time.Second * 90
const DefaultCertificateDir = "/etc/grove/ssl"
const GroveConfigFile = "grove.cfg"
const GroveConfigPath = "/etc/grove/" + GroveConfigFile
const ConfigHistory = "cfg_history/"
const RemapHistory = "remap_history/"

// Exit codes are defined in the documentation, DO NOT change to iota, to avoid ambiguity.
const (
	ExitSuccess                 = 0
	ExitError                   = 1
	ExitErrorReloadingService   = 2
	ExitErrorClearingUpdateFlag = 3
)

func AvailableStatuses() map[string]struct{} {
	return map[string]struct{}{
		"reported": {},
		"online":   {},
	}
}

func GetRemapPath() (string, error) {
	cfg, err := config.LoadConfig(GroveConfigPath)
	if err != nil {
		return "", errors.New("loading Grove config file: " + err.Error())
	}
	return cfg.RemapRulesFile, nil
}

// CopyAndGzipFile reads the src file, gzips the contents, and writes the result to dst.
func CopyAndGzipFile(src, dst string) error {
	srcF, err := os.Open(src)
	if err != nil {
		return errors.New("opening source file: " + err.Error())
	}
	defer srcF.Close()
	dstF, err := os.Create(dst)
	if err != nil {
		return errors.New("creating destination file: " + err.Error())
	}
	defer dstF.Close()

	dstFGzip := gzip.NewWriter(dstF)

	if _, err = io.Copy(dstFGzip, srcF); err != nil {
		return errors.New("copying source to destination: " + err.Error())
	}
	if err := dstFGzip.Close(); err != nil {
		return errors.New("closing destination gzip writer: " + err.Error())
	}
	if err := dstF.Sync(); err != nil {
		return errors.New("flushing copy to destination: " + err.Error())
	}
	return nil
}

// BackupFile copies the given file to a new file in the subdirectory "/remap_history", with the name suffixed by the current timestamp. Returns nil if the given file doesn't exist (nothing to back up).
func BackupFile(path string, backupDirectory string) error {
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return nil
	}

	fileTimeFormat := "2006-01-02T15_04_05_999999999Z07_00" // this is time.RFC3339Nano with : replaced by _
	backupDir := filepath.Join(filepath.Dir(path), backupDirectory)
	backupFile := filepath.Base(path) + "." + time.Now().Format(fileTimeFormat) + ".gz"
	backupPath := filepath.Join(backupDir, backupFile)

	os.MkdirAll(backupDir, os.ModePerm)

	if err := CopyAndGzipFile(path, backupPath); err != nil {
		return errors.New("backuping up remap file: " + err.Error())
	}
	return nil
}

func NewFilename(path string) string {
	return path + ".new"
}

func WriteNewFile(path string, bts []byte) error {
	newPath := NewFilename(path)
	f, err := os.Create(newPath)
	if err != nil {
		return errors.New("creating file: " + err.Error())
	}
	defer f.Close()
	if _, err := f.Write(bts); err != nil {
		return errors.New("writing file: " + err.Error())
	}
	if err := f.Sync(); err != nil {
		return errors.New("flushing file: " + err.Error())
	}
	return nil
}

// WriteAndBackup creates a backup of the existing file at the given path, then writes the given bytes to the path. The write is fail-safe on operating systems with atomic file rename (Linux is).
func WriteAndBackup(path string, backupDirectory string, bts []byte) error {
	if err := BackupFile(path, backupDirectory); err != nil {
		return errors.New("backing up file: " + err.Error())
	}
	if err := WriteNewFile(path, bts); err != nil {
		return errors.New("writing new file: " + err.Error())
	}
	if err := os.Rename(NewFilename(path), path); err != nil {
		return errors.New("copying new file to real location: " + err.Error())
	}
	return nil
}

// hasUpdatePending returns whether an update is pending, the revalPending status (which will be needed later in the clear update POST), and any error.
func hasUpdatePending(toc *to.Session, hostname string) (bool, bool, error) {
	response, _, err := toc.GetServersWithHdr(&url.Values{"hostName": {hostname}}, nil)
	if err != nil {
		return false, false, errors.New("getting update from Traffic Ops: " + err.Error())
	} else if len(response.Response) != 1 {
		return false, false, fmt.Errorf("Want exactly one server with hostname '%s', got %d", hostname, len(response.Response))
	}
	upd := response.Response
	return *upd[0].UpdPending, *upd[0].RevalPending, nil
}

// clearUpdatePending clears the given host's update pending flag in Traffic Ops. It takes the host to clear, and the old revalPending flag to send.
func clearUpdatePending(toc *to.Session, hostname string, revalPending bool) error {
	response, _, err := toc.GetServersWithHdr(&url.Values{"hostName": {hostname}}, nil)
	if err != nil {
		return fmt.Errorf("Failed to update reval_pending: %v", err)
	} else if len(response.Response) != 1 {
		return fmt.Errorf("Want exactly one server with hostname '%s', got '%d'", hostname, len(response.Response))
	}

	srv := response.Response
	srv[0].RevalPending = &revalPending
	srv[0].UpdPending = new(bool)
	alerts, _, err := toc.UpdateServerByIDWithHdr(*srv[0].ID, srv[0], nil)
	if err != nil {
		return fmt.Errorf("setting update pending on Traffic Ops: %v (Alerts: %+v)", err, alerts.Alerts)
	}
	return nil
}

func main() {
	toURL := flag.String("tourl", "", "The Traffic Ops URL")
	toUser := flag.String("touser", "", "The Traffic Ops username")
	toPass := flag.String("topass", "", "The Traffic Ops password")
	pretty := flag.Bool("pretty", false, "Whether to pretty-print output")
	ignoreUpdateFlag := flag.Bool("ignore-update-flag", false, "Whether to fetch and apply the config, without checking or updating the Traffic Ops Update Pending flag")
	host := flag.String("host", "", "The hostname of the server whose config to generate")
	toInsecure := flag.Bool("insecure", false, "Whether to allow invalid certificates with Traffic Ops")
	certDir := flag.String("certdir", DefaultCertificateDir, "Directory to save certificates to")
	noServiceReload := flag.Bool("no-service-reload", false, "Whether to avoid trying to reload the Grove service")
	flag.Parse()

	if host == nil || *host == "" {
		// if the host was not specified on the command line, get it from the kernel
		h, err := os.Hostname()
		if err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + err.Error() + " and 'host' is required, use '-host'")
			os.Exit(ExitError)
		}
		sl := strings.Split(h, ".")
		*host = sl[0]
	}

	useCache := false
	toc, _, err := to.LoginWithAgent(*toURL, *toUser, *toPass, *toInsecure, UserAgent, useCache, TrafficOpsTimeout)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error connecting to Traffic Ops: " + err.Error())
		os.Exit(ExitError)
	}

	revalPendingStatus := false
	if !*ignoreUpdateFlag {
		needsUpdate := false
		needsUpdate, revalPendingStatus, err = hasUpdatePending(toc, *host)
		if err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error checking Traffic Ops update pending: " + err.Error())
			os.Exit(ExitError)
		}
		if !needsUpdate {
			os.Exit(ExitSuccess) // if no error and no update necessary, return success and print nothing
		}
	}

	// TODO remove this once converted to 1.3 API
	// using the 1.2 API
	var hostServer tc.ServerV30
	var hostProfile tc.Profile
	var ok bool
	var profiles map[string]tc.Profile
	var servers map[string]tc.ServerV30

	serversArr, _, err := toc.GetServersWithHdr(nil, nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops Servers: " + err.Error())
		os.Exit(ExitError)
	}
	servers = makeServersHostnameMap(serversArr.Response)

	hostServer, ok = servers[*host]
	if !ok {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error: host '" + *host + "' not in Servers\n")
		os.Exit(ExitError)
	}

	profilesArr, _, err := toc.GetProfilesWithHdr(nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops Profiles: " + err.Error())
		os.Exit(ExitError)
	}
	profiles = makeProfileNameMap(profilesArr)

	hostProfile, ok = profiles[*hostServer.Profile]
	if !ok {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error: profile '" + *hostServer.Profile + "' not in Profiles\n")
		os.Exit(ExitError)
	}
	// end of API 1.2 stuff

	if hostProfile.Type == tc.GroveProfileType {
		updateRequired, cfg, err := createGroveCfg(toc, hostServer)
		if err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting config rules for '" + GroveConfigPath + "' :" + err.Error())
			os.Exit(ExitError)
		}
		if updateRequired {
			cfgBytes := []byte{}
			if *pretty {
				cfgBytes, err = json.MarshalIndent(cfg, "", "  ")
			} else {
				cfgBytes, err = json.Marshal(cfg)
			}
			if err != nil {
				fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error creating JSON Remap Rules: " + err.Error())
				os.Exit(ExitError)
			}
			if err := WriteAndBackup(GroveConfigPath, ConfigHistory, cfgBytes); err != nil {
				fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error writing new config file: " + err.Error())
				os.Exit(ExitError)
			}
		}
	} else {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Warning: the profile '" + *hostServer.Profile + "' is not a '" + tc.GroveProfileType + "', will not build a config from it.")
	}

	rules := remap.RemapRules{}
	// if *api == "1.3" {
	// 	rules, err = createRulesNewAPI(toc, *host, *certDir)
	// } else {
	rules, err = createRulesOldAPI(toc, *host, *certDir, servers) // TODO remove once 1.3 / traffic_ops_golang is deployed to production.
	// }
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error creating rules: " + err.Error())
		os.Exit(ExitError)
	}

	jsonRules, err := remap.RemapRulesToJSON(rules)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error creating JSON Remap Rules: " + err.Error())
		os.Exit(ExitError)
	}

	bts := []byte{}
	if *pretty {
		bts, err = json.MarshalIndent(jsonRules, "", "  ")
	} else {
		bts, err = json.Marshal(jsonRules)
	}

	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error marshalling rules JSON: " + err.Error())
		os.Exit(ExitError)
	}

	// TODO add app/option to print config to stdout

	remapPath, err := GetRemapPath()
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting remap config path: " + err.Error())
		os.Exit(ExitError)
	}

	if err := WriteAndBackup(remapPath, RemapHistory, bts); err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error writing new config file: " + err.Error())
		os.Exit(ExitError)
	}

	if !*noServiceReload {
		if err := exec.Command("service", "grove", "reload").Run(); err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error restarting grove service (but successfully updated config file): " + err.Error())
			os.Exit(ExitErrorReloadingService)
		}
	}

	if !*ignoreUpdateFlag {
		if err := clearUpdatePending(toc, *host, revalPendingStatus); err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error clearing update pending flag in Traffic Ops (but successfully updated config): " + err.Error())
			os.Exit(ExitErrorClearingUpdateFlag)
		}
	}

	os.Exit(ExitSuccess)
}

func createGroveCfg(toc *to.Session, server tc.ServerV30) (bool, config.Config, error) {
	var newCfg config.Config
	var currCfg config.Config
	var pluginParams = []string{}

	// load the servers current config parameters.
	if _, err := os.Stat(GroveConfigPath); err == nil {
		currCfg, err = config.LoadConfig(GroveConfigPath)
		if err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error loading current config from '" + GroveConfigPath + "' " + err.Error())
			return false, currCfg, err
		} else {
			// make sure this array is sorted for later comparison
			sort.Strings(currCfg.Plugins)
		}
	}

	serverParameters, _, err := toc.GetParametersByProfileNameWithHdr(*server.Profile, nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops Parameters for host '" + *server.HostName + "' profile '" + *server.Profile + "': " + err.Error())
		return false, currCfg, err
	} else {
		// load config parameters from the servers profile
		for _, p := range serverParameters {
			if p.ConfigFile == GroveConfigFile {
				if p.Name == "plugins" {
					pluginParams = append(pluginParams, p.Value)
				} else {
					err := setConfigParameter(&newCfg, p.Name, p.Value)
					if err != nil {
						fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error setting config parameter '" + p.Name + "' :" + err.Error())
						return false, currCfg, err
					}
				}
			}
		}
		sort.Strings(pluginParams)
		newCfg.Plugins = pluginParams
	}
	// no update is required if the configs are the same
	areEqual := reflect.DeepEqual(newCfg, currCfg)
	if areEqual == true {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " There are no changes needed to '" + GroveConfigPath + "'")
		return false, currCfg, nil
	} else { // updates are required, send the new config
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Config updates are required to '" + GroveConfigPath + "'")
		return true, newCfg, nil
	}
}

func setConfigParameter(cfg *config.Config, name string, value string) error {
	var err error

	switch name {
	case "rfc_compliant":
		cfg.RFCCompliant, err = strconv.ParseBool(value)
	case "port":
		cfg.Port, err = strconv.Atoi(value)
	case "https_port":
		cfg.HTTPSPort, err = strconv.Atoi(value)
	case "cache_size_bytes":
		cfg.CacheSizeBytes, err = strconv.Atoi(value)
	case "concurrent_rule_requests":
		cfg.ConcurrentRuleRequests, err = strconv.Atoi(value)
	case "remap_rules_file":
		cfg.RemapRulesFile = value
	case "cert_file":
		cfg.CertFile = value
	case "key_file":
		cfg.KeyFile = value
	case "interface_name":
		cfg.InterfaceName = value
	case "connection_close":
		cfg.ConnectionClose, err = strconv.ParseBool(value)
	case "log_location_error":
		cfg.LogLocationError = value
	case "log_location_warning":
		cfg.LogLocationWarning = value
	case "log_location_info":
		cfg.LogLocationInfo = value
	case "log_location_debug":
		cfg.LogLocationDebug = value
	case "log_location_event":
		cfg.LogLocationEvent = value
	case "parent_request_timeout_ms":
		cfg.ReqTimeoutMS, err = strconv.Atoi(value)
	case "parent_request_keep_alive_ms":
		cfg.ReqKeepAliveMS, err = strconv.Atoi(value)
	case "parent_request_max_idle_connections":
		cfg.ReqMaxIdleConns, err = strconv.Atoi(value)
	case "parent_request_idle_connection_timeout_ms":
		cfg.ReqIdleConnTimeoutMS, err = strconv.Atoi(value)
	case "server_idle_timeout_ms":
		cfg.ServerIdleTimeoutMS, err = strconv.Atoi(value)
	case "server_write_timeout_ms":
		cfg.ServerWriteTimeoutMS, err = strconv.Atoi(value)
	case "server_read_timeout_ms":
		cfg.ServerReadTimeoutMS, err = strconv.Atoi(value)
	case "file_mem_bytes":
		cfg.FileMemBytes, err = strconv.Atoi(value)
	default:
		err = fmt.Errorf(time.Now().Format(time.RFC3339Nano) + "No such config parameter '" + name + "', parameter ignored")
	}
	return err
}

func createRulesOldAPI(toc *to.Session, host string, certDir string, servers map[string]tc.ServerV30) (remap.RemapRules, error) {
	cachegroupsArr, _, err := toc.GetCacheGroupsNullableWithHdr(nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops Cachegroups: " + err.Error())
		os.Exit(1)
	}
	cachegroups := makeCachegroupsNameMap(cachegroupsArr)

	hostServer, ok := servers[host]
	if !ok {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error: host '" + host + "' not in Servers\n")
		os.Exit(1)
	}

	deliveryservices, _, err := toc.GetDeliveryServicesByServerWithHdr(*hostServer.ID, nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops Deliveryservices: " + err.Error())
		os.Exit(1)
	}

	deliveryserviceRegexArr, _, err := toc.GetDeliveryServiceRegexesWithHdr(nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops Deliveryservice Regexes: " + err.Error())
		os.Exit(1)
	}
	deliveryserviceRegexes := makeDeliveryserviceRegexMap(deliveryserviceRegexArr)

	cdnsArr, _, err := toc.GetCDNsWithHdr(nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops CDNs: " + err.Error())
		os.Exit(1)
	}
	cdns := makeCDNMap(cdnsArr)

	serverParameters, _, err := toc.GetParametersByProfileNameWithHdr(*hostServer.Profile, nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops Parameters for host '" + host + "' profile '" + *hostServer.Profile + "': " + err.Error())
		os.Exit(1)
	}

	parents, err := getParents(host, servers, cachegroups)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting '" + host + "' parents: " + err.Error())
		os.Exit(1)
	}

	sameCDN := func(s tc.ServerV30) bool {
		return s.CDNName == hostServer.CDNName
	}

	serverAvailable := func(s tc.ServerV30) bool {
		status := strings.ToLower(*s.Status)
		statuses := AvailableStatuses()
		_, ok := statuses[status]
		return ok
	}

	parents = filterParents(parents, sameCDN)
	parents = filterParents(parents, serverAvailable)

	cdnSSLKeys, _, err := toc.GetCDNSSLKeysWithHdr(*hostServer.CDNName, nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting '" + *hostServer.CDNName + "' SSL keys: " + err.Error())
		os.Exit(1)
	}
	dsCerts := makeDSCertMap(cdnSSLKeys)

	return createRulesOld(host, deliveryservices, parents, deliveryserviceRegexes, cdns, serverParameters, dsCerts, certDir)
}

// func createRulesNewAPI(toc *to.Session, host string, certDir string) (remap.RemapRules, error) {
// 	cacheCfg, err := toc.CacheConfig(host)
// 	if err != nil {
// 		fmt.Printf("Error getting Traffic Ops Cache Config: %v\n", err)
// 		os.Exit(1)
// 	}

// 	rules := []remapdata.RemapRule{}

// 	allowedIPs, err := makeAllowIP(cacheCfg.AllowIP)
// 	if err != nil {
// 		return remap.RemapRules{}, fmt.Errorf("creating allowed IPs: %v", err)
// 	}

// 	cdnSSLKeys, err := toc.CDNSSLKeys(cacheCfg.CDN)
// 	if err != nil {
// 		fmt.Printf("Error getting %v SSL keys: %v\n", cacheCfg.CDN, err)
// 		os.Exit(1)
// 	}
// 	dsCerts := makeDSCertMap(cdnSSLKeys)

// 	weight := DefaultRuleWeight
// 	retryNum := DefaultRetryNum
// 	timeout := DefaultTimeout
// 	parentSelection := DefaultRuleParentSelection

// 	for _, ds := range cacheCfg.DeliveryServices {
// 		protocol := ds.Protocol
// 		queryStringRule, err := getQueryStringRule(ds.QueryStringIgnore)
// 		if err != nil {
// 			return remap.RemapRules{}, fmt.Errorf("getting deliveryservice %v Query String Rule: %v", ds.XMLID, err)
// 		}

// 		protocolStrs := []ProtocolStr{}
// 		switch protocol {
// 		case ProtocolHTTP:
// 			protocolStrs = append(protocolStrs, ProtocolStr{From: "http", To: "http"})
// 		case ProtocolHTTPS:
// 			protocolStrs = append(protocolStrs, ProtocolStr{From: "https", To: "https"})
// 		case ProtocolHTTPAndHTTPS:
// 			protocolStrs = append(protocolStrs, ProtocolStr{From: "http", To: "http"})
// 			protocolStrs = append(protocolStrs, ProtocolStr{From: "https", To: "https"})
// 		case ProtocolHTTPToHTTPS:
// 			protocolStrs = append(protocolStrs, ProtocolStr{From: "http", To: "https"})
// 			protocolStrs = append(protocolStrs, ProtocolStr{From: "https", To: "https"})
// 		}

// 		cert, hasCert := dsCerts[ds.XMLID]
// 		// DEBUG
// 		// if protocol != ProtocolHTTP {
// 		// 	if !hasCert {
// 		// 		fmt.Fprint(os.Stderr, "HTTPS delivery service: "+ds.XMLID+" has no certificate!\n")
// 		// 	} else if err := createCertificateFiles(cert, certDir); err != nil {
// 		// 		fmt.Fprint(os.Stderr, "HTTPS delivery service "+ds.XMLID+" failed to create certificate: "+err.Error()+"\n")
// 		// 	}
// 		// }

// 		dsType := strings.ToLower(ds.Type)
// 		if !strings.HasPrefix(dsType, "http") && !strings.HasPrefix(dsType, "dns") {
// 			fmt.Printf("createRules skipping deliveryservice %v - unknown type %v", ds.XMLID, ds.Type)
// 			continue
// 		}

// 		for _, protocolStr := range protocolStrs {
// 			for _, dsRegex := range ds.Regexes {
// 				rule := remapdata.RemapRule{}
// 				pattern, patternLiteralRegex := trimLiteralRegex(dsRegex)
// 				rule.Name = fmt.Sprintf("%s.%s.%s.%s", ds.XMLID, protocolStr.From, protocolStr.To, pattern)
// 				rule.From = buildFrom(protocolStr.From, pattern, patternLiteralRegex, host, dsType, cacheCfg.Domain)

// 				if protocolStr.From == "https" && hasCert {
// 					rule.CertificateFile = getCertFileName(cert, certDir)
// 					rule.CertificateKeyFile = getCertKeyFileName(cert, certDir)
// 					// fmt.Fprintf(os.Stderr, "HTTPS delivery service: "+ds.XMLID+" certificate %+v\n", cert)
// 				}

// 				for _, parent := range cacheCfg.Parents {
// 					to, proxyURLStr := buildToNew(parent, protocolStr.To, ds.OriginFQDN, dsType)
// 					proxyURL, err := url.Parse(proxyURLStr)
// 					if err != nil {
// 						return remap.RemapRules{}, fmt.Errorf("error parsing deliveryservice %v parent %v proxy_url: %v", ds.XMLID, parent.Host, proxyURLStr)
// 					}

// 					ruleTo := remapdata.RemapRuleTo{
// 						RemapRuleToBase: remapdata.RemapRuleToBase{
// 							URL:      to,
// 							Weight:   &weight,
// 							RetryNum: &retryNum,
// 						},
// 						ProxyURL:   proxyURL,
// 						RetryCodes: DefaultRetryCodes(),
// 						Timeout:    &timeout,
// 					}
// 					rule.To = append(rule.To, ruleTo)
// 					// TODO get from TO?
// 					rule.RetryNum = &retryNum
// 					rule.Timeout = &timeout
// 					rule.RetryCodes = DefaultRetryCodes()
// 					rule.QueryString = queryStringRule
// 					rule.DSCP = ds.DSCP
// 					if err != nil {
// 						return remap.RemapRules{}, err
// 					}
// 					rule.ConnectionClose = DefaultRuleConnectionClose
// 					rule.ParentSelection = &parentSelection
// 				}
// 				rules = append(rules, rule)
// 			}
// 		}
// 	}

// 	remapRules := remap.RemapRules{
// 		Rules:           rules,
// 		RetryCodes:      DefaultRetryCodes(),
// 		Timeout:         &timeout,
// 		ParentSelection: &parentSelection,
// 		Stats:           remap.RemapRulesStats{Allow: allowedIPs},
// 	}

// 	return remapRules, nil
// }

func makeProfileNameMap(profiles []tc.Profile) map[string]tc.Profile {
	m := map[string]tc.Profile{}
	for _, profile := range profiles {
		m[profile.Name] = profile
	}
	return m
}

func makeServersHostnameMap(servers []tc.ServerV30) map[string]tc.ServerV30 {
	m := map[string]tc.ServerV30{}
	for _, server := range servers {
		m[*server.HostName] = server
	}
	return m
}

func makeCachegroupsNameMap(cgs []tc.CacheGroupNullable) map[string]tc.CacheGroupNullable {
	m := map[string]tc.CacheGroupNullable{}
	for _, cg := range cgs {
		if cg.Name != nil {
			m[*cg.Name] = cg
		}
	}
	return m
}

func makeDeliveryserviceRegexMap(dsrs []tc.DeliveryServiceRegexes) map[string][]tc.DeliveryServiceRegex {
	m := map[string][]tc.DeliveryServiceRegex{}
	for _, dsr := range dsrs {
		m[dsr.DSName] = dsr.Regexes
	}
	return m
}

func makeCDNMap(cdns []tc.CDN) map[string]tc.CDN {
	m := map[string]tc.CDN{}
	for _, cdn := range cdns {
		m[cdn.Name] = cdn
	}
	return m
}

func makeDSCertMap(sslKeys []tc.CDNSSLKeys) map[string]tc.CDNSSLKeys {
	m := map[string]tc.CDNSSLKeys{}
	for _, sslkey := range sslKeys {
		m[sslkey.DeliveryService] = sslkey
	}
	return m
}

func getParents(hostname string, servers map[string]tc.ServerV30, cachegroups map[string]tc.CacheGroupNullable) ([]tc.ServerV30, error) {
	server, ok := servers[hostname]
	if !ok {
		return nil, fmt.Errorf("hostname not found in Servers")
	}

	cachegroup, ok := cachegroups[*server.Cachegroup]
	if !ok {
		return nil, fmt.Errorf("server cachegroup '%v' not found in Cachegroups", server.Cachegroup)
	}

	parents := []tc.ServerV30{}
	for _, server := range servers {
		if cachegroup.ParentName != nil && *server.Cachegroup == *cachegroup.ParentName {
			parents = append(parents, server)
		}
	}
	return parents, nil
}

func filterParents(parents []tc.ServerV30, include func(tc.ServerV30) bool) []tc.ServerV30 {
	newParents := []tc.ServerV30{}
	for _, parent := range parents {
		if include(parent) {
			newParents = append(newParents, parent)
		}
	}
	return newParents
}

const ProtocolHTTP = 0
const ProtocolHTTPS = 1
const ProtocolHTTPAndHTTPS = 2
const ProtocolHTTPToHTTPS = 3

type ProtocolStr struct {
	From string
	To   string
}

// trimLiteralRegex removes the prefix and suffix in .*\.foo\.* delivery service regexes. Traffic Ops Delivery Services have regexes of this form, which aren't really regexes, and the .*\ and \.* need stripped to construct the "to" FQDN. Returns the trimmed string, and whether it was of the form `.*\.foo\.*`
func trimLiteralRegex(s string) (string, bool) {
	prefix := `.*\.`
	suffix := `\..*`
	if strings.HasPrefix(s, prefix) && strings.HasSuffix(s, suffix) {
		return s[len(prefix) : len(s)-len(suffix)], true
	}
	return s, false
}

// buildFrom builds the remap "from" URI prefix. It assumes ttype is a delivery service type HTTP or DNS, behavior is undefined for any other ttype.
func buildFrom(protocol string, pattern string, patternLiteralRegex bool, host string, dsType string, cdnDomain string) string {
	if !patternLiteralRegex {
		return protocol + "://" + pattern
	}

	if isHTTP := strings.HasPrefix(dsType, "http"); isHTTP {
		return protocol + "://" + host + "." + pattern + "." + cdnDomain
	}

	return protocol + "://" + "edge." + pattern + "." + cdnDomain
}

func dsTypeSkipsMid(ttype string) bool {
	ttype = strings.ToLower(ttype)
	if ttype == "http_no_cache" || ttype == "http_live" || ttype == "dns_live" {
		return true
	}
	if strings.Contains(ttype, "live") && !strings.Contains(ttype, "natnl") {
		return true
	}
	return false
}

// buildTo returns the to URL, and the Proxy URL (if any)
func buildTo(parentServer tc.ServerV30, protocol string, originURI string, dsType string) (string, string) {
	// TODO add port?
	to := originURI
	proxy := ""
	if !dsTypeSkipsMid(dsType) {
		proxy = "http://" + *parentServer.HostName + "." + *parentServer.DomainName + ":" + strconv.Itoa(*parentServer.TCPPort)
	}
	return to, proxy
}

// // buildToNew returns the to URL, and the Proxy URL (if any)
// func buildToNew(parent tc.CacheConfigParent, protocol string, originURI string, dsType string) (string, string) {
// 	// TODO add port?
// 	to := originURI
// 	proxy := ""
// 	if !dsTypeSkipsMid(dsType) {
// 		proxy = "http://" + parent.Host + "." + parent.Domain + ":" + strconv.FormatUint(uint64(parent.Port), 10)
// 	}
// 	return to, proxy
// }

const DeliveryServiceQueryStringCacheAndRemap = 0
const DeliveryServiceQueryStringNoCacheRemap = 1
const DeliveryServiceQueryStringNoCacheNoRemap = 2

func getQueryStringRule(dsQstringIgnore *int) (remapdata.QueryStringRule, error) {
	val := 0
	if dsQstringIgnore != nil {
		val = *dsQstringIgnore
	}
	switch val {
	case DeliveryServiceQueryStringCacheAndRemap:
		return remapdata.QueryStringRule{Remap: true, Cache: true}, nil
	case DeliveryServiceQueryStringNoCacheRemap:
		return remapdata.QueryStringRule{Remap: true, Cache: false}, nil
	case DeliveryServiceQueryStringNoCacheNoRemap:
		return remapdata.QueryStringRule{Remap: false, Cache: false}, nil
	default:
		return remapdata.QueryStringRule{}, fmt.Errorf("unknown delivery service qstringIgnore value '%v'", dsQstringIgnore)
	}
}

func DefaultRetryCodes() map[int]struct{} {
	return map[int]struct{}{}
}

const DefaultRuleWeight = 1.0
const DefaultRetryNum = 5
const DefaultTimeout = time.Millisecond * 5000
const DefaultRuleConnectionClose = false
const DefaultRuleParentSelection = remapdata.ParentSelectionTypeConsistentHash

func getAllowIP(params []tc.Parameter) ([]*net.IPNet, error) {
	ips := []string{}
	for _, param := range params {
		if (param.Name == "allow_ip" || param.Name == "allow_ip6") && param.ConfigFile == "astats.config" {
			ips = append(ips, strings.Split(param.Value, ",")...)
		}
	}
	return makeAllowIP(ips)
}

func makeAllowIP(ips []string) ([]*net.IPNet, error) {
	cidrs := make([]*net.IPNet, len(ips))
	for i, ip := range ips {
		ip = strings.TrimSpace(ip)
		if !strings.Contains(ip, "/") {
			if strings.Contains(ip, ":") {
				ip += "/128"
			} else {
				ip += "/32"
			}
		}
		_, cidrnet, err := net.ParseCIDR(ip)
		if err != nil {
			return nil, fmt.Errorf("error parsing CIDR '%s': %v", ip, err)
		}
		cidrs[i] = cidrnet
	}
	return cidrs, nil
}

func createRulesOld(
	hostname string,
	dses []tc.DeliveryServiceNullable,
	parents []tc.ServerV30,
	dsRegexes map[string][]tc.DeliveryServiceRegex,
	cdns map[string]tc.CDN,
	hostParams []tc.Parameter,
	dsCerts map[string]tc.CDNSSLKeys,
	certDir string,
) (remap.RemapRules, error) {
	rules := []remapdata.RemapRule{}
	allowedIPs, err := getAllowIP(hostParams)
	if err != nil {
		return remap.RemapRules{}, fmt.Errorf("getting allowed IPs: %v", err)
	}

	weight := DefaultRuleWeight
	retryNum := DefaultRetryNum
	timeout := DefaultTimeout
	parentSelection := DefaultRuleParentSelection

	for _, ds := range dses {
		protocol := *ds.Protocol
		queryStringRule, err := getQueryStringRule(ds.QStringIgnore)
		if err != nil {
			return remap.RemapRules{}, fmt.Errorf("getting deliveryservice %v Query String Rule: %v", ds.XMLID, err)
		}

		cdn, ok := cdns[*ds.CDNName]
		if !ok {
			return remap.RemapRules{}, fmt.Errorf("deliveryservice '%v' CDN '%v' not found", *ds.XMLID, *ds.CDNName)
		}

		protocolStrs := []ProtocolStr{}
		switch protocol {
		case ProtocolHTTP:
			protocolStrs = append(protocolStrs, ProtocolStr{From: "http", To: "http"})
		case ProtocolHTTPS:
			protocolStrs = append(protocolStrs, ProtocolStr{From: "https", To: "https"})
		case ProtocolHTTPAndHTTPS:
			protocolStrs = append(protocolStrs, ProtocolStr{From: "http", To: "http"})
			protocolStrs = append(protocolStrs, ProtocolStr{From: "https", To: "https"})
		case ProtocolHTTPToHTTPS:
			protocolStrs = append(protocolStrs, ProtocolStr{From: "http", To: "https"})
			protocolStrs = append(protocolStrs, ProtocolStr{From: "https", To: "https"})
		}

		cert, hasCert := dsCerts[*ds.XMLID]
		if protocol != ProtocolHTTP {
			if !hasCert {
				fmt.Fprint(os.Stderr, time.Now().Format(time.RFC3339Nano)+" HTTPS delivery service: "+*ds.XMLID+" has no certificate!\n")
			} else if err := createCertificateFiles(cert, certDir); err != nil {
				fmt.Fprint(os.Stderr, time.Now().Format(time.RFC3339Nano)+" HTTPS delivery service "+*ds.XMLID+" failed to create certificate: "+err.Error()+"\n")
			}
		}

		dsType := strings.ToLower(string(*ds.Type))
		if !strings.HasPrefix(dsType, "http") && !strings.HasPrefix(dsType, "dns") {
			fmt.Printf(time.Now().Format(time.RFC3339Nano)+" createRules skipping deliveryservice %v - unknown type %v", *ds.XMLID, *ds.Type)
			continue
		}

		toClientHeaders, toOriginHeaders, err := makeModHdrs(ds.EdgeHeaderRewrite, ds.RemapText)
		if err != nil {
			return remap.RemapRules{}, errors.New("Making headers for delivery service '" + *ds.XMLID + "':" + err.Error())
		}
		dsRemap := ""
		if ds.RemapText != nil {
			dsRemap = *ds.RemapText
		}
		acl, err := makeACL(dsRemap)
		if err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " createRules skipping deliveryservice '" + *ds.XMLID + "' - unsupported ACL " + dsRemap)
			continue
		}

		orgServerFQDN := ""
		if ds.OrgServerFQDN != nil {
			orgServerFQDN = *ds.OrgServerFQDN
		}

		for _, protocolStr := range protocolStrs {
			regexes, ok := dsRegexes[*ds.XMLID]
			if !ok {
				return remap.RemapRules{}, fmt.Errorf("deliveryservice '%v' has no regexes", *ds.XMLID)
			}

			for _, dsRegex := range regexes {
				rule := remapdata.RemapRule{}
				pattern, patternLiteralRegex := trimLiteralRegex(dsRegex.Pattern)
				rule.Name = fmt.Sprintf("%s.%s.%s.%s", *ds.XMLID, protocolStr.From, protocolStr.To, pattern)
				rule.From = buildFrom(protocolStr.From, pattern, patternLiteralRegex, hostname, dsType, cdn.DomainName)

				if protocolStr.From == "https" && hasCert {
					rule.CertificateFile = getCertFileName(cert, certDir)
					rule.CertificateKeyFile = getCertKeyFileName(cert, certDir)
					// fmt.Fprintf(os.Stderr, "HTTPS delivery service: "+ds.XMLID+" certificate %+v\n", cert)
				}

				rule.PluginsShared = map[string]json.RawMessage{}
				// if the delivery service skips the mid's ie, http_no_cache, http_live, and dns_live
				// only add the url rule to the origin.
				if dsTypeSkipsMid(dsType) {
					var proxyURLStr = ""
					proxyURL, err := url.Parse(proxyURLStr)
					if err != nil {
						return remap.RemapRules{}, fmt.Errorf("error parsing deliveryservice %v proxy_url: %v", *ds.XMLID, proxyURLStr)
					}
					ruleTo := remapdata.RemapRuleTo{
						RemapRuleToBase: remapdata.RemapRuleToBase{
							URL:      orgServerFQDN,
							Weight:   &weight,
							RetryNum: &retryNum,
						},
						RetryCodes: DefaultRetryCodes(),
						ProxyURL:   proxyURL,
						Timeout:    &timeout,
					}
					rule.To = append(rule.To, ruleTo)
					rule.RetryNum = &retryNum
					rule.Timeout = &timeout
					rule.RetryCodes = DefaultRetryCodes()
					rule.QueryString = queryStringRule
					rule.DSCP = *ds.DSCP
					rule.ConnectionClose = DefaultRuleConnectionClose
					rule.Allow = acl
					rule.Plugins = map[string]interface{}{}
					rule.Plugins["modify_headers"] = toClientHeaders
					rule.Plugins["modify_parent_request_headers"] = toOriginHeaders
					remapTextJSON, err := json.Marshal(dsRemap)
					if err != nil {
						return remap.RemapRules{}, fmt.Errorf("parsing deliveryservice '%v' remap text '%v' marshalling JSON: %v", *ds.XMLID, dsRemap, err)
					}
					rule.PluginsShared[web.RemapTextKey] = remapTextJSON
				} else {
					for _, parent := range parents {
						to, proxyURLStr := buildTo(parent, protocolStr.To, orgServerFQDN, dsType)
						proxyURL, err := url.Parse(proxyURLStr)
						if err != nil {
							return remap.RemapRules{}, fmt.Errorf("error parsing deliveryservice %v parent %v proxy_url: %v", *ds.XMLID, parent.HostName, proxyURLStr)
						}

						ruleTo := remapdata.RemapRuleTo{
							RemapRuleToBase: remapdata.RemapRuleToBase{
								URL:      to,
								Weight:   &weight,
								RetryNum: &retryNum,
							},
							ProxyURL:   proxyURL,
							RetryCodes: DefaultRetryCodes(),
							Timeout:    &timeout,
						}
						rule.To = append(rule.To, ruleTo)
						// TODO get from TO?
						rule.RetryNum = &retryNum
						rule.Timeout = &timeout
						rule.RetryCodes = DefaultRetryCodes()
						rule.QueryString = queryStringRule
						rule.DSCP = *ds.DSCP
						rule.ConnectionClose = DefaultRuleConnectionClose
						rule.ParentSelection = &parentSelection
						rule.Allow = acl
						rule.Plugins = map[string]interface{}{}
						rule.Plugins["modify_headers"] = toClientHeaders
						rule.Plugins["modify_parent_request_headers"] = toOriginHeaders
						remapTextJSON, err := json.Marshal(dsRemap)
						if err != nil {
							return remap.RemapRules{}, fmt.Errorf("parsing deliveryservice '%v' remap text '%v' marshalling JSON: %v", *ds.XMLID, dsRemap, err)
						}
						rule.PluginsShared[web.RemapTextKey] = remapTextJSON
					}
				}
				rules = append(rules, rule)
			}
		}
	}

	globalPlugins := map[string]interface{}{}
	serverHeader := web.Hdr{Name: "Server", Value: "Grove/0.33"}
	setHeaders := []web.Hdr{}
	setHeaders = append(setHeaders, serverHeader)
	globalHeaders := web.ModHdrs{Set: setHeaders}
	globalPlugins["modify_response_headers_global"] = globalHeaders
	remapRules := remap.RemapRules{
		Rules:           rules,
		RetryCodes:      DefaultRetryCodes(),
		Timeout:         &timeout,
		ParentSelection: &parentSelection,
		Stats:           remapdata.RemapRulesStats{Allow: allowedIPs},
		Plugins:         globalPlugins,
	}

	return remapRules, nil
}

func getCertFileName(cert tc.CDNSSLKeys, dir string) string {
	return dir + string(os.PathSeparator) + strings.Replace(cert.Hostname, "*.", "", -1) + ".crt"
}

func getCertKeyFileName(cert tc.CDNSSLKeys, dir string) string {
	return dir + string(os.PathSeparator) + strings.Replace(cert.Hostname, "*.", "", -1) + ".key"
}

func createCertificateFiles(cert tc.CDNSSLKeys, dir string) error {
	certFileName := getCertFileName(cert, dir)
	crt, err := base64.StdEncoding.DecodeString(cert.Certificate.Crt)
	if err != nil {
		return errors.New("base64decoding certificate file " + certFileName + ": " + err.Error())
	}
	if err := ioutil.WriteFile(certFileName, crt, 0644); err != nil {
		return errors.New("writing certificate file " + certFileName + ": " + err.Error())
	}

	keyFileName := getCertKeyFileName(cert, dir)
	key, err := base64.StdEncoding.DecodeString(cert.Certificate.Key)
	if err != nil {
		return errors.New("base64decoding certificate key " + keyFileName + ": " + err.Error())
	}
	if err := ioutil.WriteFile(keyFileName, key, 0644); err != nil {
		return errors.New("writing certificate key file " + keyFileName + ": " + err.Error())
	}
	return nil
}

// makeACL is a hack to take the very ATS/TrafficControl remap_text field ACLs, and turn them into grove ACLs
// note that the astats ACL input already has CIDR notation, but the DS ACL input is IP ranges.
func makeACL(remapTxt string) ([]*net.IPNet, error) {
	allow := []*net.IPNet{}
	remapTxt = strings.Join(strings.Fields(remapTxt), " ")
	// We only have @action=allow not @action=deny, and only @scr_ip= not @in_op=
	// so only worrying about that here.
	if strings.HasPrefix(remapTxt, "@action=allow") {
		remaps := strings.Split(remapTxt, " ")
		if len(remaps) < 2 {
			return nil, errors.New("malformed remapTxt '" + remapTxt + "'")
		}
		for _, allowStr := range remaps[1:] {
			allBits := 32
			if strings.Contains(allowStr, ":") {
				allBits = 128 // not sure if v6 works, only tested with our v4 ACLs.
			}
			if strings.Contains(allowStr, "-") {
				a := strings.Split(strings.TrimPrefix(allowStr, "@src_ip="), "-")
				if len(a) < 2 {
					return nil, errors.New("malformed remapTxt '" + remapTxt + "'")
				}
				startAddrStr := a[0]
				endAddrStr := a[1]
				start := net.ParseIP(startAddrStr)
				end := net.ParseIP(endAddrStr)
				if start == nil || end == nil {
					// This error catches all unexpected (but valid) options.
					return nil, fmt.Errorf("error parsing allow string: %v, %v", allowStr, remapTxt)
				}
				maskBits := allBits
				mask := net.CIDRMask(maskBits, allBits)
				for !start.Mask(mask).Equal(end.Mask(mask)) {
					maskBits--
					mask = net.CIDRMask(maskBits, allBits)
				}
				fmt.Println(time.Now().Format(time.RFC3339Nano)+" DEBUG base: ", startAddrStr, " end:", endAddrStr, " maskBits:", maskBits) // TODO remove?
				allow = append(allow, &net.IPNet{IP: start.Mask(mask), Mask: mask})
			} else {
				addrStr := strings.Trim(allowStr, "@src_ip=")
				addr := net.ParseIP(addrStr)
				if addr == nil {
					// This error catches all unexpected (but valid) options.
					return nil, fmt.Errorf("error parsing allow string: %v, %v", allowStr, remapTxt)
				}
				mask := net.CIDRMask(allBits, allBits)
				allow = append(allow, &net.IPNet{IP: addr.Mask(mask), Mask: mask})
			}
		}
	}
	return allow, nil
}

// makeModHdrs is a pretty nasty hack to take the very ATS/TrafficControl specific config stuff from Traffic Ops and turn it into header manipulation rules for grove.
// Returns the client header modifications, the origin header modifications, and any error.
func makeModHdrs(edgeHRWin *string, remapTXTin *string) (web.ModHdrs, web.ModHdrs, error) {

	edgeHRW := ""
	remapTXT := ""
	if edgeHRWin != nil {
		edgeHRW = *edgeHRWin
	}
	if remapTXTin != nil {
		remapTXT = *remapTXTin
	}
	if edgeHRW == "" && remapTXT == "" {
		return web.ModHdrs{}, web.ModHdrs{}, nil
	}

	// Normalize the whitespaces to just a single " "
	edgeHRW = strings.Join(strings.Fields(edgeHRW), " ")
	remapTXT = strings.Join(strings.Fields(remapTXT), " ")

	toClientList := web.ModHdrs{}
	toOriginList := web.ModHdrs{}
	if strings.Contains(edgeHRW, "-header") {
		toOrigin := true
		for _, line := range strings.Split(edgeHRW, "__RETURN__") {
			line = strings.TrimSuffix(line, "[L]")
			parts := strings.Fields(line)
			if len(parts) == 0 {
				continue
			}
			if len(parts) < 2 {
				return web.ModHdrs{}, web.ModHdrs{}, errors.New("edge header rewrite: malformed line '" + line + "'")
			}
			switch {
			case parts[0] == "cond":
				if parts[1] == "%{SEND_RESPONSE_HDR_HOOK}" {
					toOrigin = false
				}
				if parts[1] == "%{SEND_REQUEST_HDR_HOOK}" {
					toOrigin = true
				}
			case parts[0] == "set-header" || parts[0] == "add-header": // Technically these are different
				if len(parts) < 3 {
					return web.ModHdrs{}, web.ModHdrs{}, errors.New("edge header rewrite: malformed line '" + line + "'")
				}
				hdr := web.Hdr{Name: parts[1], Value: strings.Join(parts[2:], " ")}
				if toOrigin {
					toOriginList.Set = append(toOriginList.Set, hdr)
				} else {
					toClientList.Set = append(toClientList.Set, hdr)
				}
			case parts[0] == "rm-header":
				if toOrigin {
					toOriginList.Drop = append(toOriginList.Drop, parts[1])
				} else {
					toClientList.Drop = append(toClientList.Drop, parts[1])
				}
			}
		}
	}

	return toClientList, toOriginList, nil
}
