package main

import (
	"context"
	"fmt"
	"testing"
	"time"

	confMetrics "github.com/pingcap-inc/clinic/clinic_data_service/pkg/config/metrics"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/constant"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/log"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/prometheus"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/s3"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/thirdapi/o11y"
	"github.com/stretchr/testify/assert"
	"go.uber.org/zap"
)

var clusterId = "10355969091959802668"
var sqlDigest = "5ac605ec38e39c09bc5f58d10238dfde9da42077e839df42d16b297a703d1526"
var queryTime = "20251203"

func TestMaxCPUTimeIn5MinWindow(t *testing.T) {
	Init()
	clusterId := "10218000100066887827"
	sqlDigest := "C211C18E8F8F07E610DF43A0561E64BFD5826B7748E7860E6542B2E6C6086142"
	queryTime := prometheus.GetDayQueryTime(queryTime)
	maxCPUTimeResp, err := prometheus.GetMaxCPUTimeIn5MinWindow(clusterId, sqlDigest, "1d", queryTime)
	log.PlainInfo("max cpu time", zap.Any("max", maxCPUTimeResp))
	if err != nil {
		log.PlainError("GetMaxCPUTime failed", zap.Error(err))
	}
	if maxCPUTimeResp != nil {
		timeStr, err := prometheus.GetMax5MinWindowTime(clusterId, sqlDigest, maxCPUTimeResp.Instance)
		if err != nil {
			log.PlainError("GetMax5MinWindowTime failed", zap.Error(err))
		}
		log.PlainInfo("max cpu time", zap.Any("max", maxCPUTimeResp), zap.Any("time", timeStr))
	}

}

/*
	func GetMax5MinWindowTime(t *testing.T) {
		Init()
		// clusterId := "1379661944646416027"
		// sqlDigest := "1575b6af5f6a51f3b1bec9eeca30355aebfadf51f8a624e2da6a777c731ca9a9"
		maxCPUTimeResp, err := prometheus.GetMaxCPUTimeIn5MinWindow(clusterId, sqlDigest)
		if err != nil {
			t.Fatalf("GetMaxCPUTime failed: %v", err)
		}
		timeStr, err := prometheus.GetMax5MinWindowTime(clusterId, sqlDigest, maxCPUTimeResp.Instance, queryTime)
		log.PlainInfo("max cpu time", zap.Any("max", maxCPUTimeResp), zap.Any("time", timeStr))

}
*/
func TestGetTotalCPUTime(t *testing.T) {
	Init()
	clusterId := "1379661944646416027"
	// sqlDigest := "18576E217F5F93FA2A934F84290447CAA4B783CAB493503C4AD71C912EA16930"
	sqlDigest := "8A4714033A3F43EF18A98F5E1470F302BBB6FEE753BB496D38C81C648CD89AA4"
	day := "20250922"
	total, err := prometheus.GetTotalCpuTimeByDigest(clusterId, sqlDigest, day)
	total2, err := prometheus.GetTotalCpuTimeByDigest2(clusterId, sqlDigest, day)
	if err != nil {
		t.Fatalf("GetTotalCPUTime failed: %v", err)
	}
	log.PlainInfo("total cpu time（old）", zap.Float64("total", *total/60))
	log.PlainInfo("total cpu time（new）", zap.Float64("total", *total2/60))

}

func TestCheckCPU(t *testing.T) {
	Init()
	clusterIds := []string{"1379661944646416027"}
	dayStr := "20250814"
	// digest := "03121066433134986EA3DB382E222D23A390C8A70EA550A9E5A96541BC09E4F3"
	digest := "c84895fa0b47afebadafeb97635daaf1464b96d90fb8abceff50e7879e91912c"

	resp, err := prometheus.CheckCPU(clusterIds, dayStr, digest)
	if err != nil {
		t.Fatalf("TestCheckCPU failed: %v", err)
	}
	log.PlainInfo("CheckCPU result", zap.Any("resp", resp))
}

func TestGetTotalCountForDay(t *testing.T) {
	Init()
	clusterId := "1379661944646416027"

	dayStr := "20250805"
	total, err := prometheus.GetTotalCountForDay(clusterId, dayStr)
	if err != nil {
		t.Fatalf("GetTotalCountForDay failed: %v", err)
	}
	log.PlainInfo("total count for day", zap.Float64("total", total))

}

func TestGetTotalDigestForDay(t *testing.T) {
	Init()
	clusterId := "1379661944646416027"

	dayStr := "20250805"
	digestCount, total, err := prometheus.GetTotalDigestForDay(clusterId, dayStr)
	if err != nil {
		t.Fatalf("GetTotalDigestForDay failed: %v", err)
	}
	log.PlainInfo("total count for day", zap.Float64("total", total), zap.Float64("digestCount", digestCount))

}

func TestGetTopXCPUConsumingSQLForDay(t *testing.T) {
	Init()
	clusterId := "1379661944646416027"

	dayStr := "20250805"
	top := 10
	usages, err := prometheus.GetTopXCPUConsumingSQLForDay(clusterId, dayStr, top)
	if err != nil {
		t.Fatalf("GetTopXCPUConsumingSQLForDay failed: %v", err)
	}
	log.PlainInfo("top x cpu consuming sql for day", zap.Int("top", top))
	// fmt.Sprintf("usages: %v", usages)
	log.PlainInfo(fmt.Sprintf("%v", usages))
}

func TestGetTopXSQLCPUUsagePercentageForDay(t *testing.T) {
	Init()
	clusterId := "1379661944646416027"

	dayStr := "20250805"
	top := 20
	// query := `sum by (sql_digest) (sum_over_time(topsql_cpu_time_ms[1d]))`
	query := `topk(10, sum by (sql_digest) (sum_over_time(topsql_cpu_time_ms{sql_digest!=""，tag_label="" }[1d])))`

	interval := 24 * time.Hour
	totalCPUTime, cpuUsagePercentage, err := prometheus.GetTopXSQLCPUUsagePercentageForDay(clusterId, dayStr, top, query, interval)
	if err != nil {
		t.Fatalf("GetTopXSQLCPUUsagePercentageForDay failed: %v", err)
	}
	log.PlainInfo("top x sql cpu usage percentage for day", zap.Int("top", top), zap.Float64("totalCPUTime", totalCPUTime), zap.Float64("cpuUsagePercentage", cpuUsagePercentage))
	// fmt.Sprintf("totalCPUTime: %v, cpuUsagePercentage: %v", totalCPUTime, cpuUsagePercentage)
	log.PlainInfo(fmt.Sprintf("totalCPUTime: %v, cpuUsagePercentage: %v", totalCPUTime, cpuUsagePercentage))
}

func TestGetTotalSQLCount(t *testing.T) {
	Init()
	clusterId := "1379661944646416027"

	dayStr := "20250805"
	top := 15
	totalCount, err := prometheus.GetTotalSQLCount(clusterId, dayStr)
	if err != nil {
		t.Fatalf("GetTotalSQLCount failed: %v", err)
	}
	log.PlainInfo("top x sql cpu usage percentage for day", zap.Int("top", top), zap.Float64("totalCount", totalCount))
	// fmt.Sprintf("totalCount: %v", totalCount)
	log.PlainInfo(fmt.Sprintf("totalCount: %v", totalCount))
}

// TestGetTotalCount24Hours tests getting SQL execution count within 24 hours
func TestGetTotalCount24Hours(t *testing.T) {
	Init()
	clusterId := "1379661944646416027"
	dayStr := "20250805"
	// query := fmt.Sprintf(`sum(sum_over_time(topsql_stmt_exec_count{instance_type="tidb",cluster_id="%s"}[30m]))`, clusterId)
	query := fmt.Sprintf(`sum(sum_over_time(topsql_stmt_exec_count{instance_type="tidb",cluster_id="%s"}[30m]* 30))`, clusterId)

	// Calculate SQL execution count accumulated in 30-minute intervals within a day
	total, err := prometheus.GetSumValueForDay(clusterId, dayStr, query, 30*time.Minute)
	if err != nil {
		t.Fatalf("GetSumValueForDay failed: %v", err)
	}

	log.PlainInfo("total count for 24 hours", zap.Float64("total", total))

}

/*
// TestGetTotalCount24Hours tests getting SQL execution count within 24 hours
func TestGetTotalCPU24Hours(t *testing.T) {
	Init()
	// clusterId := "1379661944646416027"
	clusterId := "10727759767757299112"
	p := 0.999
	endTime, _ := time.Parse(time.RFC3339, "2025-11-28T11:04:04Z")

	// Calculate SQL execution count accumulated in 5-minute intervals within a day
	total, err := prometheus.GetClusterLatency(clusterId, p, endTime, "360s")
	if err != nil {
		t.Fatalf("GetClusterLatency failed: %v", err)
	}

	log.PlainInfo("total count for 24 hours", zap.Float64("total", total))

}

*/

func TestTopXCount(t *testing.T) {
	Init()
	//clusterId := "10727759767757299112"
	// clusterId := "10731923822720459339"  //premium
	// clusterId := "10490128323027520380"  //premium
	clusterId := "1379661944646416027" //premium

	aInterval := "1d"
	topN := 10
	aQueryTime, _ := time.Parse(time.RFC3339, "2025-11-05T05:04:04Z")

	topA, err := prometheus.GetTopXCountHistoryData(clusterId, aInterval, topN, aQueryTime)
	log.PlainInfo("top x count for day", zap.Int("top", topN), zap.Any("topA", topA))
	assert.NoError(t, err)
}

func TestGetTiDBInstances(t *testing.T) {
	Init()
	clusterId := "10818379321594918728"
	// clusterId := "10731923822720459339"  //premium
	// clusterId := "10490128323027520380"  //premium
	queryTime, _ := time.Parse(time.RFC3339, "2025-12-13T00:00:00Z")

	instances, err := prometheus.GetTiDBInstances(clusterId, queryTime, "1h")
	log.PlainInfo("top x count for day", zap.Any("instances count", len(instances)), zap.Any("instances", instances))
	assert.NoError(t, err)
}

func TestGetPrometheusURL(t *testing.T) {
	Init()
	confMetrics.InitForMetrics()
	p := o11y.QueryClusterReq{
		Region:        "us-east-1",
		TenantID:      "1372813089209061633",
		BizType:       string(constant.BizTypeTidbCloud),
		ApplicationID: "10788149070073621874",
		Vendor:        string(constant.ProviderAWS),
	}
	url, err := o11y.GetPrometheusURL(context.Background(), p)
	assert.NoError(t, err)
	assert.NotEmpty(t, url)
	// log.PlainInfo("prometheus url", zap.String("url", url))
}
func TestGetO11yCluster(t *testing.T) {
	Init()
	confMetrics.InitForMetrics()

	// dedicatedUrl cluster
	p := o11y.QueryClusterReq{
		Region:        "ap-southeast-1",
		TenantID:      "10155276127061229449",
		BizType:       string(constant.BizTypeTidbCloud),
		ApplicationID: "10155276127061229449",
		Vendor:        string(constant.ProviderAWS),
		// ProjectID:     "1372813089454576996",
	}

	//  node Iops premium
	// p := o11y.QueryClusterReq{
	// 	Region:        "ap-southeast-1",
	// 	TenantID:      "1372813089209289635",
	// 	BizType:       string(constant.BizTypeNextGen),
	// 	ApplicationID: "dp-efd8e128-be23-4a15-932b-ad51a5cd6426",
	// 	Vendor:        string(constant.ProviderAliCloud),

	// }

	//  cluster metric
	// p := o11y.QueryClusterReq{
	// 	Region:        "ap-southeast-1",
	// 	TenantID:      "1372813089209289635",
	// 	BizType:       string(constant.BizTypeNextGen),
	// 	ApplicationID: "10537830824162030296",
	// 	Vendor:        string(constant.ProviderAliCloud),

	// }

	// wetech  dedicated  cluster metrics
	// p := o11y.QueryClusterReq{
	// 	Region:        "us-east-1",
	// 	TenantID:      "1372813089209061633",
	// 	BizType:       string(constant.BizTypeTidbCloud),
	// 	ApplicationID: "1379661944646416027",
	// 	Vendor:        string(constant.ProviderAWS),
	// }

	// // wetech dataplan metrics
	// p := o11y.QueryClusterReq{
	// 	Region:        "us-east-1",
	// 	TenantID:      "1372813089209061633",
	// 	BizType:       string(constant.BizTypeTidbCloud),
	// 	ApplicationID: string(constant.ApplicationIDK8sInfra),
	// 	Vendor:        string(constant.ProviderAWS),
	// 	ProjectID:     "1372813089454544954",
	// }

	// ue
	// p := o11y.QueryClusterReq{
	// 	Region:        "us-east-1",
	// 	TenantID:      "1372813089188151296", // gogamecdc test
	// 	BizType:       string(constant.BizTypeTidbCloud),
	// 	ApplicationID: "10400917620589115003",
	// 	Vendor:        string(constant.ProviderAWS),
	// 	ProjectID:     "1372813089454583500",
	// }

	//
	// p := o11y.QueryClusterReq{
	// 	Region:        "us-east-1",
	// 	TenantID:      "1372813089208881414",
	// 	BizType:       string(constant.BizTypeTidbCloud),
	// 	ApplicationID: "10080549812876629319",
	// 	Vendor:        string(constant.ProviderAWS),
	// 	ProjectID:     "1372813089454593350",
	// }

	cluster, err := o11y.GetPrometheusURL(context.Background(), p)
	assert.NoError(t, err)
	assert.NotEmpty(t, cluster)

}

func TestDeleteClusterMetricsRouting(t *testing.T) {
	Init()

	req := s3.GetDeleteClusterAppIdReq{
		ClusterID: "10892260000245137880",
		Region:    "cn-hongkong",
		OrgID:     "1372813089209301464",
		// ProjectID: "1372813089454583500",
	}

	/*

		req := s3.GetDeleteClusterAppIdReq{
			ClusterID: "1372813089188151296",
			Region:    "us-east-1",
			OrgID:     "1372813089209061633",
			ProjectID: "1372813089454583500",
		}
	*/

	metricsRouting := s3.GetDeleteClusterAppId(context.Background(), req)
	log.PlainInfo("cluster.yaml content", zap.String("content", metricsRouting))

}
