package go_http

import (
	"fmt"

	"code.justin.tv/dta/twitch-create-service/internal/grafana/structs"
)

type App struct {
}

var _ structs.AppType = (*App)(nil)

func (a *App) NewRows(owner, name string) ([]*structs.Row, error) {
	return []*structs.Row{
		newTopGometricsRow(name),
		newBottomGometricsRow(name),
	}, nil
}

func newTopGometricsRow(name string) *structs.Row {
	r := &structs.Row{
		Editable: true,
		Height:   "250px",
		Panels: []*structs.Panel{
			newNumGoroutinesPanel(2, name),
			newMemAllocationPanel(3, name),
			newMemHeapPanel(4, name),
		},
	}

	return r
}

func newBottomGometricsRow(name string) *structs.Row {
	r := &structs.Row{
		Editable: true,
		Height:   "250px",
		Panels: []*structs.Panel{
			newGCCollectionsPanel(5, name),
			newGCPausePanel(6, name),
			newGCCPUPanel(7, name),
		},
	}

	return r
}

func newNumGoroutinesPanel(id int, name string) *structs.Panel {
	return structs.NewPanel(id, 4, "Number of Goroutines", "", "", false, []structs.Target{
		{
			RefID:  "A",
			Target: fmt.Sprintf("averageSeries(stats.gauges.%v.$env.*.go.num_goroutines)", name),
		},
	}, "")
}

func newMemAllocationPanel(id int, name string) *structs.Panel {
	return structs.NewPanel(id, 4, "Memory - Allocation Rate", "per second", "", true, []structs.Target{
		{
			RefID:  "A",
			Target: fmt.Sprintf("aliasByNode(averageSeriesWithWildcards(stats.counters.%v.$env.*.go.mem.*.rate, 4), 6)", name),
		},
	}, "")
}

func newMemHeapPanel(id int, name string) *structs.Panel {
	return structs.NewPanel(id, 4, "Memory - Heap", "", "", false, []structs.Target{
		{
			RefID:  "A",
			Target: fmt.Sprintf("averageSeries(stats.gauges.%v.$env.*.go.mem.heap_objects)", name),
		},
	}, "")
}

func newGCCollectionsPanel(id int, name string) *structs.Panel {
	return structs.NewPanel(id, 4, "GC - Collection Rate", "collections per second", "", false, []structs.Target{
		{
			RefID:  "A",
			Target: fmt.Sprintf("averageSeries(stats.counters.%v.$env.*.go.gc.collections.rate)", name),
		},
	}, "")
}

func newGCPausePanel(id int, name string) *structs.Panel {
	return structs.NewPanel(id, 4, "GC - Pause Duration", "", "", true, []structs.Target{
		{
			RefID:  "A",
			Target: fmt.Sprintf("aliasByNode(averageSeriesWithWildcards(stats.timers.%v.$env.*.go.gc.total_duration.{mean,p90,p99}, 4), 7)", name),
		},
	}, "")
}

func newGCCPUPanel(id int, name string) *structs.Panel {
	return structs.NewPanel(id, 4, "GC - CPU Utilization", "%", "", false, []structs.Target{
		{
			RefID:  "A",
			Target: fmt.Sprintf("averageSeriesWithWildcards(stats.gauges.%v.$env.*.go.gc.percent_cpu, 4)", name),
		},
	}, "")
}
