package hook

import (
	"fmt"
	"time"

	"github.com/elliotchance/pie/v2"
	"github.com/prometheus/client_golang/prometheus"
	export_metric "github.com/tidbcloud/dataflow-service/app/metrics/backup_export/metric"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"gorm.io/gorm"
)

type backupExportMetricsHooker struct{}

var _ entity.DataflowEventHooker = (*backupExportMetricsHooker)(nil)

func NewBackupExportMetricsHooker() *backupExportMetricsHooker {
	return &backupExportMetricsHooker{}
}

func (b *backupExportMetricsHooker) BeforeSave(tx *gorm.DB, v interface{}) {
}

func (b *backupExportMetricsHooker) AfterSave(tx *gorm.DB, v interface{}) {
	export, ok := v.(*entity.BackupExport)
	if !ok {
		return
	}
	export_metric.UpdateBackupExportStatusMetric(export)
	// delete the metrics of the backup exports that are in final status
	// note that prometheus will scrape the metrics every 1 minute, so we delete the metrics after 2 minute
	// to make sure prometheus has scraped the metrics
	// we may introduce worker pool to do this job in the future(check goroutine metrics in after launch this feature)
	if export.DeletedAt != nil ||
		pie.Contains(entity.FinalBackupExportStatuses, export.Status) {
		go func() {
			time.Sleep(export_metric.WaitMetricScrapeInterval)
			export_metric.BackupExportStatus.DeletePartialMatch(
				prometheus.Labels{export_metric.BackupExportIDLabel: fmt.Sprintf("%d", export.ID)})
		}()
	}
}

func (b *backupExportMetricsHooker) Type() entity.DataflowEventType {
	return entity.BackupExportDisplayType
}
