package metrics

import (
	"context"
	"fmt"
	"time"

	"github.com/tidbcloud/account/internel/svc/admin"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/tidbcloud/account/commons/database"
	"github.com/tidbcloud/account/internel/dao/entity"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"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"},
		nil)
)

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

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()
	ctx := context.Background()
	defer func() {
		tilog.Info(ctx, "tenant info metrics collect time", zap.Int64("time", time.Since(start).Milliseconds()))
	}()
	var tenants []entity.Tenant
	err := database.Transaction(func(tx *gorm.DB) error {
		return entity.NewTenantQuerySet(tx).All(&tenants)
	})
	if err != nil {
		tilog.Error(ctx, "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), "", "", "")
	}
}
