package catapult_test

import (
	"encoding/json"
	"testing"

	. "fuchsia.googlesource.com/testing/catapult"
	schema "fuchsia.googlesource.com/testing/perf/schema/v1"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
)

type HistogramTestSuite struct {
	suite.Suite
}

func TestHistogram(t *testing.T) {
	suite.Run(t, new(HistogramTestSuite))
}

func (s *HistogramTestSuite) TestConvertVariantsToHistograms() {
	var perfTestOutput = []byte(`{
			"variants": [{
				"finish_time": 1234567,
				"variant_desc": "example_variant",
				"boot_args": "example_boot_arg1",
				"fbenchmarks_data": [{
					"label": "example_benchmark_data",
					"unit": "ns",
					"samples": [{
						"label": "example_sample",
						"values": [10, 20, 30, 40, 50]
					}]
				}]
			}]
		}
		`)

	var variants struct {
		Variants []schema.Variant
	}

	json.Unmarshal(perfTestOutput, &variants)
	histogramSet := ConvertVariantsToHistograms(variants.Variants)
	histogram := histogramSet[0]

	assert.Equal(s.T(), len(histogramSet), 1)
	assert.Equal(s.T(), histogram.Name, "example_variant, example_benchmark_data")
	assert.Len(s.T(), histogram.GUID, 36)
	assert.Equal(s.T(), histogram.Unit, "timeInMsAutoFormat_smallerIsBetter")
	assert.Empty(s.T(), histogram.Description)
	assert.Empty(s.T(), histogram.Diagnostics)
	assert.ElementsMatch(s.T(), histogram.SampleValues, []float64{
		1e-5,
		2e-5,
		3e-5,
		4e-5,
		5e-5,
	})
	assert.Equal(s.T(), histogram.MaxNumSampleValues, 5)
	assert.Equal(s.T(), histogram.NumNans, 0)
	assert.ElementsMatch(s.T(), histogram.Running, []float64{
		5,     // count
		5e-05, // max
		0,     // meanlogs
		3.0000000000000004e-05, //mean
		1e-5, // min
		1.5000000000000001e-4, //sum
		2.5e-10,               // variance
	})
}
