package metric

import (
	"fmt"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/samber/lo"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
)

const (
	NS                      = "dataflow"
	SUBSYSTEM_CRRF          = "crrf"
	SUBSYSTEM_CRRF_WORKFLOW = "crrf_workflow"

	TenantIDLabel        = "tenant_id"
	ProjectIDLabel       = "project_id"
	ClusterIDLabel       = "cluster_id"
	IDLabel              = "crrf_id"
	LogBackupIDLabel     = "log_backup_id"
	MasterRegionLabel    = "master_region"
	SecondaryRegionLabel = "secondary_region"

	BusinessActionLabel = "business_action"
	WorkflowStatusLabel = "status"
	DeletedLabel        = "deleted"

	WaitMetricScrapeInterval = time.Minute * 2
)

var (
	statusCommonLabels = []string{TenantIDLabel, ProjectIDLabel, ClusterIDLabel, IDLabel, LogBackupIDLabel}
)

var (
	//nolint:gomnd
	StatusIntMap = map[entity.CRRFSettingStatus]int{
		entity.CRRFSettingStatusDisabled:  1,
		entity.CRRFSettingStatusEnabling:  2,
		entity.CRRFSettingStatusEnabled:   3,
		entity.CRRFSettingStatusDisabling: 4,
		entity.CRRFSettingStatusFailed:    5,
	}

	StatusDesc = prometheus.NewDesc(
		prometheus.BuildFQName(NS, SUBSYSTEM_CRRF, "status_desc"),
		"the status of CRRF.",
		statusCommonLabels, nil)

	Status = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Namespace:   NS,
			Subsystem:   SUBSYSTEM_CRRF,
			Name:        "status",
			Help:        "CRRF status: 1 - disabled, 2 - enabling, 3 - enabled, 4 - disabling, 5 - failed",
			ConstLabels: nil,
		}, lo.Concat(statusCommonLabels, []string{MasterRegionLabel, SecondaryRegionLabel, DeletedLabel}))
)

func UpdateStatusMetric(crrf *entity.CRRFSetting) {
	Status.WithLabelValues(
		fmt.Sprintf("%d", crrf.TenantID),
		fmt.Sprintf("%d", crrf.ProjectID),
		fmt.Sprintf("%d", crrf.ClusterID),
		fmt.Sprintf("%d", crrf.ID),
		fmt.Sprintf("%d", crrf.LogBackupID),
		crrf.MasterRegion,
		crrf.SecondaryRegion,
		fmt.Sprintf("%t", !crrf.DeletedAt.Time.IsZero()),
	).Set(float64(StatusIntMap[crrf.Status]))
}

func DeleteStatusMetric(crrf *entity.CRRFSetting) {
	Status.DeletePartialMatch(prometheus.Labels{
		IDLabel: fmt.Sprintf("%d", crrf.ID),
	})
}
