package template

import (
	"bufio"
	"bytes"
	"text/template"

	"github.com/juju/errors"
	"github.com/pingcap/schrodinger/config"
	"github.com/pingcap/schrodinger/pkg/types"
	"github.com/pingcap/schrodinger/util"
)

const (
	// BriefReportTemplateName represents brief report template name
	BriefReportTemplateName = "brief-experiment-report"
	// BriefReportTemplate represents brief report
	BriefReportTemplate = "```" + `
State: {{.State}}     Stage: {{.Stage}}
VERSION:
pd: {{.Config.PDConfig.Version.Value}}({{.RunVersion.PDVersion.Value}})
tidb: {{.Config.TiDBConfig.Version.Value}}({{.RunVersion.TiDBVersion.Value}})
tikv: {{.Config.TiKVConfig.Version.Value}}({{.RunVersion.TiKVVersion.Value}})
{{range .Tests}}{{if eq .Status  "FAILED"}}
Error Case Name: {{.Name}}
Logs:
` + "{{.Log}}" + `{{end}}{{end}}

detail report: <{{.DetailLink}} |{{.DetailLink}}>` + "```"

	// DetailReportTemplateName represents detail report template name
	DetailReportTemplateName = "detail-experiment-report"
	// BenchReportTemplateName represents bench report template name
	BenchReportTemplateName = "bench-report"
	// BenchReportTemplate represents bench report
	BenchReportTemplate = "```" + `
Version:
pd / tidb / tikv: {{.Config.PDConfig.Version.Value}} / {{.Config.TiDBConfig.Version.Value}} / {{.Config.TiKVConfig.Version.Value}}
Create Time: {{.Ctime}}
experiment: {{.Name}}
{{range $index, $test := .TestResults}}
test-{{$index}}: < {{$test.TestName}} >
    * QPS / EPS : {{formatFloat64 $test.QPS}} / {{formatFloat64 $test.EPS}} ({{float64ToPercentage $test.QPSDiff}} / {{float64ToPercentage $test.EPSDiff}})
    * AvgMs : {{formatFloat64 $test.AvgMs}} ({{float64ToPercentage $test.AvgMsDiff}})
    * PercentileMs90 : {{formatFloat64 $test.Pct90}} ({{float64ToPercentage $test.Pct90Diff}})
    * PercentileMs99 : {{formatFloat64 $test.Pct99}} ({{float64ToPercentage $test.Pct99Diff}}){{range .QueryResults}}
	<Query: {{.Query}}>
	* Cost: {{.Cost}} ({{float64ToPercentage .Diff}}){{end}}{{end}}

History: {{.BenchHistoryLink}}` + "```"
)

// GenDetailReportTemplate gens detailReportTemplate
func GenDetailReportTemplate() string {
	return `
ssh ` + config.GetGlobalConfig().JumpServerHost + `
password: ` + config.GetGlobalConfig().JumpServerPasswd + `

State: {{.State}}
Stage: {{.Stage}}
Destroyed : {{.Destroyed}}

VERSION:
pd: {{.Config.PDConfig.Version.Value}}({{.RunVersion.PDVersion.Value}}) {{.RunVersion.PDVersion.BuildTime}}
tidb: {{.Config.TiDBConfig.Version.Value}}({{.RunVersion.TiDBVersion.Value}}) {{.RunVersion.TiDBVersion.BuildTime}}
tikv: {{.Config.TiKVConfig.Version.Value}}({{.RunVersion.TiKVVersion.Value}}) {{.RunVersion.TiKVVersion.BuildTime}}

Create Time: {{.Ctime}}
Update Time: {{.Utime}}
Namespace: {{.Namespace}}

ClusterSize:
pd: {{.Config.PDConfig.Size}}
tidb: {{.Config.TiDBConfig.Size}}
tikv: {{.Config.TiKVConfig.Size}}

Error Cases:{{range .Tests}}{{if eq .Status  "FAILED"}}
Name: {{.Name}}
Logs:
{{.Log}}{{end}}{{end}}

{{if .Cat}}

TiDB cluster:
connection to TiDB LB: mysql -uroot -h {{index .Cat.Cluster.NodeIP 0}} -P {{.Cat.Cluster.TidbService.NodePort}}
granfana addr: {{index .Cat.Cluster.NodeIP 0}}:{{.Cat.Cluster.GrafanaService.NodePort}}
prometheus addr: {{index .Cat.Cluster.NodeIP 0}}:{{.Cat.Cluster.PrometheusService.NodePort}}


TiDB nodes:{{range .Cat.Cluster.TidbStatus}}
PodName: {{.Name}}
PodIP: {{.PodIP}}
Client CMD: mysql -uroot -P 4000 -h {{.PodIP}}
Log: {{.LogAddr}}
{{end}}


TiKV nodes:{{range .Cat.Cluster.TikvStatus}}
PodName: {{.Name}}
PodIP: {{.PodIP}}
Log: {{.LogAddr}}
{{end}}


PD nodes:{{range .Cat.Cluster.PdStatus}}
PodName: {{.Name}}
PodIP: {{.PodIP}}
Log: {{.LogAddr}}
{{end}}

Ctls:
Pd ctl    :  pd-ctl -u http://{{.Cat.Cluster.PdService.ClusterIP}}:{{.Cat.Cluster.PdService.ClusterPort}}
Tidb ctl  :  tidb-ctl -H {{.Cat.Cluster.TidbService.ClusterIP}} -P {{.Cat.Cluster.TidbService.ClusterPort}}
Tikv ctl  : {{range .Cat.Cluster.TikvStatus}}
	     tikv-ctl -H {{.PodIP}}:20160
			{{end}}

{{end}}
Case Logs:{{range .Tests}}
{{.Name}}: {{.LogPath}}
{{end}}

APP Logs:{{range .APPs}}
{{.Name}}: {{.LogPath}}
{{end}}
`
}

var funcMap = template.FuncMap{
	"float64ToPercentage": util.Float64ToPercentage,
	"formatFloat64":       util.FormatFloat64,
}

// GenerateReport returns specified report
func GenerateReport(name string, tmpl string, report *types.ExperimentReport) (string, error) {
	var (
		b      bytes.Buffer
		writer = bufio.NewWriter(&b)
	)

	t := template.Must(template.New(name).Funcs(funcMap).Parse(tmpl))
	err := t.Execute(writer, report)

	writer.Flush()
	return b.String(), errors.Trace(err)
}
