package handler

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/observability/o11ymetering/pkg/common/constants"
	"github.com/tidbcloud/observability/o11ymetering/pkg/common/models"
	"github.com/tidbcloud/observability/pkg/common/configs"
	o11yconstants "github.com/tidbcloud/observability/pkg/common/constants"
	"github.com/tidbcloud/observability/pkg/common/structs"
)

func TestUtil_ConvertMetricCollectionRespToRecords(t *testing.T) {
	configs.Init(structs.ServiceInfo{
		Region: "us-east-1",
		Vendor: "aws",
	})
	task := models.StatisticTask{
		ID: "1", Region: "us-east-1", StatisticClass: constants.MetricsCollection,
		MeteringGroup: constants.DedicatedRegionalControl, Env: constants.Prod,
		Period: "2023-01-01 00:00:00", State: constants.StatePending,
	}
	resp := &models.O11yMetricsResponse{Data: models.O11yMetrics{Result: []models.O11yMetricsResult{
		{O11yMetricsLabelSet: models.O11yMetricsLabelSet{Tenant: "t1", Project: "p1", TidbCluster: "c1", Component: "comp1", ComponentID: "compid1", Container: "cont1"}, Value: []interface{}{float64(1), "123.45"}},
	}}}
	records := convertMetricCollectionRespToRecords(constants.MetricsTimeseriesCount, constants.Metrics, resp, task)
	assert.Len(t, records, 1)
	assert.Equal(t, 123.45, records[0].Value)
	assert.Equal(t, "t1", records[0].ClusterMeta.Tenant)
	assert.Equal(t, "compid1", records[0].SubCategory)
}

func TestUtil_Getters(t *testing.T) {
	assert.Equal(t, "test_tenant", getTenant(models.O11yMetricsLabelSet{Tenant: "test_tenant"}))
	assert.Equal(t, "undefined", getTenant(models.O11yMetricsLabelSet{}))
	assert.Equal(t, "test_project", getProject(models.O11yMetricsLabelSet{Project: "test_project"}))
	assert.Equal(t, "test_label_project", getProject(models.O11yMetricsLabelSet{LabelProject: "test_label_project"}))
	assert.Equal(t, "test_tidb_cluster", getCluster(models.O11yMetricsLabelSet{TidbCluster: "test_tidb_cluster"}))
	assert.Equal(t, "test_label_tidbcloud_cluster", getCluster(models.O11yMetricsLabelSet{LabelTidbcloud_Cluster: "test_label_tidbcloud_cluster"}))
	assert.Equal(t, "test_component", getComponent(models.O11yMetricsLabelSet{Component: "test_component"}))
	assert.Equal(t, "test_label_component", getComponent(models.O11yMetricsLabelSet{LabelComponent: "test_label_component"}))
	assert.Equal(t, "test_component_id", getSubCategory(models.O11yMetricsLabelSet{ComponentID: "test_component_id"}))
	assert.Equal(t, "test_container", getContainer(models.O11yMetricsLabelSet{Container: "test_container"}))
	assert.Equal(t, "test_container_name", getContainer(models.O11yMetricsLabelSet{ContainerName: "test_container_name"}))
}

func TestUtil_ConvertPeriodToTimestamp(t *testing.T) {
	assert.Equal(t, 10, convertPeriodToTimestamp("2023-07-23 10:30:00").Hour())
	assert.Panics(t, func() { convertPeriodToTimestamp("invalid") })
}

func TestUtil_ConvertVendorToProvider(t *testing.T) {
	assert.Equal(t, "eks", convertVendorToProvider(string(o11yconstants.AWS)))
	assert.Equal(t, "gke", convertVendorToProvider(string(o11yconstants.GCP)))
	assert.Panics(t, func() { convertVendorToProvider("azure") })
}

func TestUtil_ConvertValue(t *testing.T) {
	assert.Equal(t, 123.45, convertValue("123.45"))
	assert.Equal(t, 0.0, convertValue(""))
	assert.Equal(t, 0.0, convertValue("invalid"))
}

func TestUtil_RenderS3ComponentType(t *testing.T) {
	configs.Init(structs.ServiceInfo{
		Region: "us-east-1",
		Vendor: "aws",
	})
	assert.Equal(t, "query_template_aws_s3", renderS3ComponentType("query_template_%s"))
	configs.Init(structs.ServiceInfo{
		Region: "us-east-1",
		Vendor: "gcp",
	})
	assert.Equal(t, "query_template_gcp_cloud_storage", renderS3ComponentType("query_template_%s"))
}
