package metrics

import (
	"github.com/pingcap/dbaas/central/db"
	"github.com/pingcap/dbaas/central/db/entity"
	"github.com/pingcap/log"
	"github.com/prometheus/client_golang/prometheus"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

var (
	DevTierTenantCount = prometheus.NewDesc(
		prometheus.BuildFQName("dbaas", "dev_tier", "tenant_num"),
		"The number of tenant who used dev tier cluster",
		[]string{"kind"},
		nil)
)

type MetricsCollector struct {
}

func NewMetricsCollector() *MetricsCollector {
	return &MetricsCollector{}
}

func (c *MetricsCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- DevTierTenantCount
}

func (c *MetricsCollector) Collect(ch chan<- prometheus.Metric) {
	var clusters []entity.Cluster
	err := db.Transaction(func(tx *gorm.DB) error {
		return entity.NewClusterQuerySet(tx).FreeEq(true).PreloadTenant().All(&clusters)
	})
	if err != nil {
		log.Error("Get cluster from database failed", zap.Error(err))
		return
	}
	tenant := make(map[entity.ID]struct{}, len(clusters))
	var internal, external float64
	for _, cluster := range clusters {
		if _, ok := tenant[cluster.TenantID]; ok {
			continue
		}
		tenant[cluster.TenantID] = struct{}{}
		if cluster.Tenant.Kind == entity.TenantKindInternal {
			internal++
		} else {
			external++
		}
	}

	ch <- prometheus.MustNewConstMetric(
		DevTierTenantCount,
		prometheus.CounterValue,
		internal,
		string(entity.TenantKindInternal),
	)

	ch <- prometheus.MustNewConstMetric(
		DevTierTenantCount,
		prometheus.CounterValue,
		external,
		string(entity.TenantKindExternal),
	)
}
