func parseHealthCheckProtocol(checks []marathonHealthCheck) string {
	for _, check := range checks {
		if check.Protocol != "HTTP" && check.Protocol != "HTTPS" {
			continue
		}
		return check.Protocol
	}
	return ""
}
/* maybe combine this with the above?
package marathon
import (
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"sort"
	"strings"
	"time"
	"github.com/QubitProducts/bamboo/configuration"
)
const (
	taskStateRunning                           = "TASK_RUNNING"
	readinessCheckDefaultTimeout time.Duration = 10 * time.Second
	readinessCheckSafetyMargin   time.Duration = 5 * time.Second
)
type readinessCalculator struct {
	checkDefaultTimeout time.Duration
	checkSafetyMargin   time.Duration
}
var readyCalculator = readinessCalculator{
	checkDefaultTimeout: readinessCheckDefaultTimeout,
	checkSafetyMargin:   readinessCheckSafetyMargin,
}
type Task struct {
	Id    string
	Host  string
	Port  int
	Ports []int
	Alive bool
	State string
	Ready bool
}
type HealthCheck struct {
	Protocol string
	Path string
	PortIndex int
}
type App struct {
	Id                  string
	MesosDnsId          string
	EscapedId           string
	HealthCheckPath     string
	HealthCheckProtocol string
	HealthChecks        []HealthCheck
	ReadinessCheckPath  string
	Tasks               []Task
	ServicePort         int
	ServicePorts        []int
	Env                 map[string]string
	Labels              map[string]string
	SplitId             []string
	IpAddress           AppIpAddress `json:"ipAddress"`
}
type AppIpAddress struct {
	Discovery Discovery `json:"discovery"`
}
type Discovery struct {
	Ports []Port `json:"ports"`
}
type Port struct {
	Number   int    `json:"number"`
	Name     string `json:"name"`
	Protocol string `json:"protocol"`
}
type TaskIpAddress struct {
	IpAddress string `json:"ipAddress"`
	Protocol  string `json:"protocol"`
}
type AppList []App
func (slice AppList) Len() int {
	return len(slice)
}
func (slice AppList) Less(i, j int) bool {
	return slice[i].Id < slice[j].Id
}
func (slice AppList) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
type HealthCheckResult struct {
	Alive bool
}
type marathonTask struct {
	AppId              string
	Id                 string
	Host               string
	Ports              []int
	ServicePorts       []int
	State              string
	StartedAt          string
	StagedAt           string
	Version            string
	IpAddresses        []TaskIpAddress `json:"IpAddresses"`
	HealthCheckResults []HealthCheckResult
}
type marathonTaskList []marathonTask
func (slice marathonTaskList) Len() int {
	return len(slice)
}
func (slice marathonTaskList) Less(i, j int) bool {
	return slice[i].Id < slice[j].Id
}
func (slice marathonTaskList) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
type marathonApps struct {
	Apps []marathonApp `json:"apps"`
}
type marathonApp struct {
	Id                    string                   `json:"id"`
	HealthChecks          []marathonHealthCheck    `json:"healthChecks"`
	Ports                 []int                    `json:"ports"`
	Env                   map[string]string        `json:"env"`
	Labels                map[string]string        `json:"labels"`
	Deployments           []deployment             `json:"deployments"`
	Tasks                 marathonTaskList         `json:"tasks"`
	ReadinessChecks       []marathonReadinessCheck `json:"readinessChecks"`
	ReadinessCheckResults []readinessCheckResult   `json:"readinessCheckResults"`
	IpAddress             AppIpAddress             `json:"ipAddress"`
}
type marathonHealthCheck struct {
	Path      string `json:"path"`
	Protocol  string `json:"protocol"`
	PortIndex int    `json:"portIndex"`
}
type marathonReadinessCheck struct {
	Path           string `json:"path"`
	TimeoutSeconds int    `json:"timeoutSeconds"`
}
type deployment struct {
	ID string `json:"id"`
}
type readinessCheckResult struct {
	TaskID string `json:"taskId"`
	Ready  bool   `json:"ready"`
}
func FetchApps(maraconf configuration.Marathon, conf *configuration.Configuration) (AppList, error) {
	var marathonApps []marathonApp
	var err error
	for _, url := range maraconf.Endpoints() {
		marathonApps, err = fetchMarathonApps(url, conf)
		if err == nil {
			for _, marathonApp := range marathonApps {
				sort.Sort(marathonApp.Tasks)
			}
			apps := createApps(marathonApps)
			sort.Sort(apps)
			return apps, nil
		}
	}
	return nil, err
}
func fetchMarathonApps(endpoint string, conf *configuration.Configuration) ([]marathonApp, error) {
	var appResponse marathonApps
	if err := parseJSON(endpoint+"/v2/apps?embed=app.tasks&embed=app.deployments&embed=app.readiness", conf, &appResponse); err != nil {
		return nil, err
	}
	return appResponse.Apps, nil
}
func parseJSON(url string, conf *configuration.Configuration, out interface{}) error {
	client := &http.Client{}
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Add("Accept", "application/json")
	req.Header.Add("Content-Type", "application/json")
	if len(conf.Marathon.User) > 0 && len(conf.Marathon.Password) > 0 {
		req.SetBasicAuth(conf.Marathon.User, conf.Marathon.Password)
	}
	response, err := client.Do(req)
	if err != nil {
		return err
	}
	defer response.Body.Close()
	contents, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return err
	}
	err = json.Unmarshal(contents, &out)
	if err != nil {
		return err
	}
	return nil
}
func createApps(marathonApps []marathonApp) AppList {
	apps := AppList{}
	for _, mApp := range marathonApps {
		appId := mApp.Id
		appPath := "/" + strings.TrimPrefix(mApp.Id, "/")
		app := App{
			Id:                  appPath,
			MesosDnsId:          getMesosDnsId(appPath),
			EscapedId:           strings.Replace(appId, "/", "::", -1),
			HealthCheckPath:     parseHealthCheckPath(mApp.HealthChecks),
			HealthCheckProtocol: parseHealthCheckProtocol(mApp.HealthChecks),
			ReadinessCheckPath:  parseReadinessCheckPath(mApp.ReadinessChecks),
			Env:                 mApp.Env,
			Labels:              mApp.Labels,
			SplitId:             strings.Split(appId, "/"),
			IpAddress:           mApp.IpAddress,
		}
		app.HealthChecks = make([]HealthCheck, 0, len(mApp.HealthChecks))
		for _, marathonCheck := range mApp.HealthChecks {
			check := HealthCheck{
				Protocol:  marathonCheck.Protocol,
				Path:      marathonCheck.Path,
				PortIndex: marathonCheck.PortIndex,
			}
			app.HealthChecks = append(app.HealthChecks, check)
		}
		if len(mApp.Ports) > 0 {
			app.ServicePort = mApp.Ports[0]
			app.ServicePorts = mApp.Ports
		}
		tasks := []Task{}
		for _, mTask := range mApp.Tasks {
			var host string
			var port int
			if len(mTask.Ports) > 0 {
				host = mTask.Host
				port = mTask.Ports[0]
			}
			if len(app.IpAddress.Discovery.Ports) > 0 {
				if len(mTask.IpAddresses) > 0 {
					host = mTask.IpAddresses[0].IpAddress
					port = app.IpAddress.Discovery.Ports[0].Number
				}
			}
			if host != "" && port != 0 {
				t := Task{
					Id:    mTask.Id,
					Host:  host,
					Port:  port,
					Ports: mTask.Ports,
					Alive: calculateTaskHealth(mTask.HealthCheckResults, mApp.HealthChecks),
					Ready: readyCalculator.calculate(mTask, mApp),
					State: mTask.State,
				}
				tasks = append(tasks, t)
			}
		}
		app.Tasks = tasks
		apps = append(apps, app)
	}
	return apps
}
func getMesosDnsId(appPath string) string {
	groups := strings.Split(appPath, "/")
	reverseGroups := []string{}
	for i := len(groups) - 1; i >= 0; i-- {
		if groups[i] != "" {
			reverseGroups = append(reverseGroups, groups[i])
		}
	}
	return strings.Join(reverseGroups, "-")
}
func parseHealthCheckPath(checks []marathonHealthCheck) string {
	for _, check := range checks {
		if check.Protocol != "HTTP" && check.Protocol != "HTTPS" {
			continue
		}
		return check.Path
	}
	return ""
}