package collector

import (
	"context"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/tidbcloud/dataflow-service/app/container"
	restore_metric "github.com/tidbcloud/dataflow-service/app/metrics/restore/metric"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"github.com/tidbcloud/dataflow-service/pkg/log"
	"go.uber.org/zap"
)

type restoreMetricsCollector struct{}

func NewRestoreMetricsCollector() prometheus.Collector {
	return &restoreMetricsCollector{}
}

func (c *restoreMetricsCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- restore_metric.RestoreStatusDesc
}

func (c *restoreMetricsCollector) Collect(ch chan<- prometheus.Metric) {
	logger := log.GetLogger(context.Background()).Named("restoreMetricsCollector")
	start := time.Now()
	defer func() {
		logger.Info("restore metrics collect time", zap.Int64("time in millisecond", time.Since(start).Milliseconds()))
	}()

	ctx := context.Background()
	app := container.Global()

	// restore(in pending status) are created in dataflow-http pod by console or in dataflow-grpc pod by open-api
	// but only dataflow-worker pod exposes metrics, so we need polling to collect metrics for pending backups
	restores, err := app.RestoreRepo.List(ctx, func(qs entity.RestoreQuerySet) entity.RestoreQuerySet {
		return qs.StatusIn(entity.RestoreStatusPENDING)
	})
	if err != nil {
		logger.Error("retrieve restore failed", zap.Error(err))
		return
	}
	logger.Info("total pending restore", zap.Int("restore list length", len(restores)))
	for _, r := range restores {
		restore_metric.UpdateRestoreStatusMetric(&r)
	}
}
