package main

import (
	"fmt"
	"io"
	"text/template"
	"time"
)

const templ = `
		cross	within 	total
txs		{{ .CrossDC.Txs.Count }}	{{ .SameDC.Txs.Count }}	{{ .Total.Txs.Count }}
	client
	p50	{{ .CrossDC.Txs.Client.Quantile 0.50 | Nanos }}	{{ .SameDC.Txs.Client.Quantile 0.50 | Nanos }}	{{ .Total.Txs.Client.Quantile 0.50 | Nanos }}
	p75	{{ .CrossDC.Txs.Client.Quantile 0.75 | Nanos }}	{{ .SameDC.Txs.Client.Quantile 0.75 | Nanos }}	{{ .Total.Txs.Client.Quantile 0.75 | Nanos }}
	p90	{{ .CrossDC.Txs.Client.Quantile 0.90 | Nanos }}	{{ .SameDC.Txs.Client.Quantile 0.90 | Nanos }}	{{ .Total.Txs.Client.Quantile 0.90 | Nanos }}
	p95	{{ .CrossDC.Txs.Client.Quantile 0.95 | Nanos }}	{{ .SameDC.Txs.Client.Quantile 0.95 | Nanos }}	{{ .Total.Txs.Client.Quantile 0.95 | Nanos }}
	p99	{{ .CrossDC.Txs.Client.Quantile 0.99 | Nanos }}	{{ .SameDC.Txs.Client.Quantile 0.99 | Nanos }}	{{ .Total.Txs.Client.Quantile 0.99 | Nanos }}
	p999	{{ .CrossDC.Txs.Client.Quantile 0.999 | Nanos }}	{{ .SameDC.Txs.Client.Quantile 0.999 | Nanos }}	{{ .Total.Txs.Client.Quantile 0.999 | Nanos }}

	service
	p50	{{ .CrossDC.Txs.Service.Quantile 0.50 | Nanos }}	{{ .SameDC.Txs.Service.Quantile 0.50 | Nanos }}	{{ .Total.Txs.Service.Quantile 0.50 | Nanos }}
	p75	{{ .CrossDC.Txs.Service.Quantile 0.75 | Nanos }}	{{ .SameDC.Txs.Service.Quantile 0.75 | Nanos }}	{{ .Total.Txs.Service.Quantile 0.75 | Nanos }}
	p90	{{ .CrossDC.Txs.Service.Quantile 0.90 | Nanos }}	{{ .SameDC.Txs.Service.Quantile 0.90 | Nanos }}	{{ .Total.Txs.Service.Quantile 0.90 | Nanos }}
	p95	{{ .CrossDC.Txs.Service.Quantile 0.95 | Nanos }}	{{ .SameDC.Txs.Service.Quantile 0.95 | Nanos }}	{{ .Total.Txs.Service.Quantile 0.95 | Nanos }}
	p99	{{ .CrossDC.Txs.Service.Quantile 0.99 | Nanos }}	{{ .SameDC.Txs.Service.Quantile 0.99 | Nanos }}	{{ .Total.Txs.Service.Quantile 0.99 | Nanos }}
	p999	{{ .CrossDC.Txs.Service.Quantile 0.999 | Nanos }}	{{ .SameDC.Txs.Service.Quantile 0.999 | Nanos }}	{{ .Total.Txs.Service.Quantile 0.999 | Nanos }}

	network
	p50	{{ .CrossDC.Txs.Network.Quantile 0.50 | Nanos }}	{{ .SameDC.Txs.Network.Quantile 0.50 | Nanos }}	{{ .Total.Txs.Network.Quantile 0.50 | Nanos }}
	p75	{{ .CrossDC.Txs.Network.Quantile 0.75 | Nanos }}	{{ .SameDC.Txs.Network.Quantile 0.75 | Nanos }}	{{ .Total.Txs.Network.Quantile 0.75 | Nanos }}
	p90	{{ .CrossDC.Txs.Network.Quantile 0.90 | Nanos }}	{{ .SameDC.Txs.Network.Quantile 0.90 | Nanos }}	{{ .Total.Txs.Network.Quantile 0.90 | Nanos }}
	p95	{{ .CrossDC.Txs.Network.Quantile 0.95 | Nanos }}	{{ .SameDC.Txs.Network.Quantile 0.95 | Nanos }}	{{ .Total.Txs.Network.Quantile 0.95 | Nanos }}
	p99	{{ .CrossDC.Txs.Network.Quantile 0.99 | Nanos }}	{{ .SameDC.Txs.Network.Quantile 0.99 | Nanos }}	{{ .Total.Txs.Network.Quantile 0.99 | Nanos }}
	p999	{{ .CrossDC.Txs.Network.Quantile 0.999 | Nanos }}	{{ .SameDC.Txs.Network.Quantile 0.999 | Nanos }}	{{ .Total.Txs.Network.Quantile 0.999 | Nanos }}

calls		{{ .CrossDC.Calls.Count }}	{{ .SameDC.Calls.Count }}	{{ .Total.Calls.Count }}
	client
	p50	{{ .CrossDC.Calls.Client.Quantile 0.50 | Nanos }}	{{ .SameDC.Calls.Client.Quantile 0.50 | Nanos }}	{{ .Total.Calls.Client.Quantile 0.50 | Nanos }}
	p75	{{ .CrossDC.Calls.Client.Quantile 0.75 | Nanos }}	{{ .SameDC.Calls.Client.Quantile 0.75 | Nanos }}	{{ .Total.Calls.Client.Quantile 0.75 | Nanos }}
	p90	{{ .CrossDC.Calls.Client.Quantile 0.90 | Nanos }}	{{ .SameDC.Calls.Client.Quantile 0.90 | Nanos }}	{{ .Total.Calls.Client.Quantile 0.90 | Nanos }}
	p95	{{ .CrossDC.Calls.Client.Quantile 0.95 | Nanos }}	{{ .SameDC.Calls.Client.Quantile 0.95 | Nanos }}	{{ .Total.Calls.Client.Quantile 0.95 | Nanos }}
	p99	{{ .CrossDC.Calls.Client.Quantile 0.99 | Nanos }}	{{ .SameDC.Calls.Client.Quantile 0.99 | Nanos }}	{{ .Total.Calls.Client.Quantile 0.99 | Nanos }}
	p999	{{ .CrossDC.Calls.Client.Quantile 0.999 | Nanos }}	{{ .SameDC.Calls.Client.Quantile 0.999 | Nanos }}	{{ .Total.Calls.Client.Quantile 0.999 | Nanos }}

	service
	p50	{{ .CrossDC.Calls.Service.Quantile 0.50 | Nanos }}	{{ .SameDC.Calls.Service.Quantile 0.50 | Nanos }}	{{ .Total.Calls.Service.Quantile 0.50 | Nanos }}
	p75	{{ .CrossDC.Calls.Service.Quantile 0.75 | Nanos }}	{{ .SameDC.Calls.Service.Quantile 0.75 | Nanos }}	{{ .Total.Calls.Service.Quantile 0.75 | Nanos }}
	p90	{{ .CrossDC.Calls.Service.Quantile 0.90 | Nanos }}	{{ .SameDC.Calls.Service.Quantile 0.90 | Nanos }}	{{ .Total.Calls.Service.Quantile 0.90 | Nanos }}
	p95	{{ .CrossDC.Calls.Service.Quantile 0.95 | Nanos }}	{{ .SameDC.Calls.Service.Quantile 0.95 | Nanos }}	{{ .Total.Calls.Service.Quantile 0.95 | Nanos }}
	p99	{{ .CrossDC.Calls.Service.Quantile 0.99 | Nanos }}	{{ .SameDC.Calls.Service.Quantile 0.99 | Nanos }}	{{ .Total.Calls.Service.Quantile 0.99 | Nanos }}
	p999	{{ .CrossDC.Calls.Service.Quantile 0.999 | Nanos }}	{{ .SameDC.Calls.Service.Quantile 0.999 | Nanos }}	{{ .Total.Calls.Service.Quantile 0.999 | Nanos }}

	network
	p50	{{ .CrossDC.Calls.Network.Quantile 0.50 | Nanos }}	{{ .SameDC.Calls.Network.Quantile 0.50 | Nanos }}	{{ .Total.Calls.Network.Quantile 0.50 | Nanos }}
	p75	{{ .CrossDC.Calls.Network.Quantile 0.75 | Nanos }}	{{ .SameDC.Calls.Network.Quantile 0.75 | Nanos }}	{{ .Total.Calls.Network.Quantile 0.75 | Nanos }}
	p90	{{ .CrossDC.Calls.Network.Quantile 0.90 | Nanos }}	{{ .SameDC.Calls.Network.Quantile 0.90 | Nanos }}	{{ .Total.Calls.Network.Quantile 0.90 | Nanos }}
	p95	{{ .CrossDC.Calls.Network.Quantile 0.95 | Nanos }}	{{ .SameDC.Calls.Network.Quantile 0.95 | Nanos }}	{{ .Total.Calls.Network.Quantile 0.95 | Nanos }}
	p99	{{ .CrossDC.Calls.Network.Quantile 0.99 | Nanos }}	{{ .SameDC.Calls.Network.Quantile 0.99 | Nanos }}	{{ .Total.Calls.Network.Quantile 0.99 | Nanos }}
	p999	{{ .CrossDC.Calls.Network.Quantile 0.999 | Nanos }}	{{ .SameDC.Calls.Network.Quantile 0.999 | Nanos }}	{{ .Total.Calls.Network.Quantile 0.999 | Nanos }}

roots		{{ .CrossDC.Roots.Count }}	{{ .SameDC.Roots.Count }}	{{ .Total.Roots.Count }}
	total service time
	p50	{{ .CrossDC.Roots.Service.Quantile 0.50 | Nanos }}	{{ .SameDC.Roots.Service.Quantile 0.50 | Nanos }}	{{ .Total.Roots.Service.Quantile 0.50 | Nanos }}
	p75	{{ .CrossDC.Roots.Service.Quantile 0.75 | Nanos }}	{{ .SameDC.Roots.Service.Quantile 0.75 | Nanos }}	{{ .Total.Roots.Service.Quantile 0.75 | Nanos }}
	p90	{{ .CrossDC.Roots.Service.Quantile 0.90 | Nanos }}	{{ .SameDC.Roots.Service.Quantile 0.90 | Nanos }}	{{ .Total.Roots.Service.Quantile 0.90 | Nanos }}
	p95	{{ .CrossDC.Roots.Service.Quantile 0.95 | Nanos }}	{{ .SameDC.Roots.Service.Quantile 0.95 | Nanos }}	{{ .Total.Roots.Service.Quantile 0.95 | Nanos }}
	p99	{{ .CrossDC.Roots.Service.Quantile 0.99 | Nanos }}	{{ .SameDC.Roots.Service.Quantile 0.99 | Nanos }}	{{ .Total.Roots.Service.Quantile 0.99 | Nanos }}
	p999	{{ .CrossDC.Roots.Service.Quantile 0.999 | Nanos }}	{{ .SameDC.Roots.Service.Quantile 0.999 | Nanos }}	{{ .Total.Roots.Service.Quantile 0.999 | Nanos }}

services touched:
	{{ range $s := .Total.Services.All }}{{ $s }}
	{{ end }}
datacenters touched:
	{{ range $dc := .Total.Datacenters.All }}{{ $dc }}
	{{ end }}
cross-dc services:
	{{ range $s := .CrossDC.Services.All }}{{ $s }}
	{{ end }}
`

var templFns = template.FuncMap{
	"Nanos": func(ns float64) time.Duration {
		return (time.Duration(ns) / time.Millisecond) * time.Millisecond
	},
	"Pct": func(num, den int) string {
		return fmt.Sprintf("%.2f%%", float64(num)*100.0/float64(den))
	},
}

func dump(r *results, w io.Writer) error {
	t := template.Must(template.New("results").Funcs(templFns).Parse(templ))
	return t.Execute(w, r)
}
