package metrics

import (
	"fmt"
	"time"

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

var (
	tenantInfo = prometheus.NewDesc(
		prometheus.BuildFQName("dbaas", "tenant", "info"),
		"Information about tenant",
		[]string{"tenant", "name", "status", "shoot", "region", "plan", "kind"},
		nil)
)

func RegisterMetrics(am *admin.Model) {
	prometheus.MustRegister(NewTenantCollector(am))
	prometheus.MustRegister(NewMetricsCollector())
}

type TenantCollector struct {
	am *admin.Model
}

func NewTenantCollector(am *admin.Model) *TenantCollector {
	return &TenantCollector{am}
}

func (c *TenantCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- tenantInfo
}

func (c *TenantCollector) Collect(ch chan<- prometheus.Metric) {
	var start = time.Now()
	defer func() {
		log.Info("tenant info metrics collect time", zap.Int64("time", time.Since(start).Milliseconds()))
	}()
	var tenants []entity.Tenant
	err := db.Transaction(func(tx *gorm.DB) error {
		return entity.NewTenantQuerySet(tx).All(&tenants)
	})
	if err != nil {
		log.Error("failed to list tenants", zap.Error(err))
		return
	}

	for _, tenant := range tenants {
		tenantStr := fmt.Sprintf("%d", tenant.ID)
		ch <- prometheus.MustNewConstMetric(tenantInfo, prometheus.GaugeValue, 1.0, tenantStr, tenant.Name,
			string(tenant.Status), "", "", string(tenant.Plan), string(tenant.Kind))
	}
}
