package hook

import (
	"fmt"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	backup_metric "github.com/tidbcloud/dataflow-service/app/metrics/backup/metric"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"gorm.io/gorm"
)

type backupMetricsHooker struct{}

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

func NewBackupMetricsHooker() *backupMetricsHooker {
	return &backupMetricsHooker{}
}

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

func (b *backupMetricsHooker) AfterSave(tx *gorm.DB, v interface{}) {
	backup, ok := v.(*entity.Backup)
	if !ok {
		return
	}
	backup_metric.UpdateBackupStatusMetric(backup)
	// delete the metrics of the backups 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 backup.DeletedAt != nil ||
		(backup.Status != entity.BackupStatusRunning && backup.Status != entity.BackupStatusPending) {
		go func() {
			time.Sleep(backup_metric.WaitMetricScrapeInterval)
			backup_metric.BackupStatus.DeletePartialMatch(
				prometheus.Labels{backup_metric.BackupIDLabel: fmt.Sprintf("%d", backup.ID)})
		}()
	}
}

func (b *backupMetricsHooker) Type() entity.DataflowEventType {
	return entity.BackupDisplayType
}
