package metrics

import (
	"fmt"

	"github.com/prometheus/client_golang/prometheus"

	"github.com/tidbcloud/dataflow-service/internal/db/entity"
)

const (
	dmSubSystem = "dm"

	jobIDLabel       = "job_id"
	StageLabel       = "stage"
	StepLabel        = "step"
	ReasonClassLabel = "reason_class"
)

// DMJobDurationInPhase duration for some dm-job stays in some phase, we only use this to record duration in
// Creating and Deleting phase
var DMJobDurationInPhase = prometheus.NewGaugeVec(
	prometheus.GaugeOpts{
		Namespace: DataflowNamespace,
		Subsystem: dmSubSystem,
		Name:      "job_duration_in_phase",
		Help:      "Duration for a job stays in some phase",
	}, []string{TenantLabel, ClusterIDLabel, jobIDLabel, "phase"})

// DMCreateStageFailedTotal counts direct create-stage failures after the DM job
// has left the "creating" phase (StateDeploy succeeded) and entered StateDump.
var DMCreateStageFailedTotal = prometheus.NewCounterVec(
	prometheus.CounterOpts{
		Namespace: DataflowNamespace,
		Subsystem: dmSubSystem,
		Name:      "create_stage_failed_total",
		Help:      "Total number of DM create-stage failures in the dump phase after the job left creating",
	}, []string{TenantLabel, ClusterIDLabel, jobIDLabel, StageLabel, ReasonClassLabel})

// DMModifyFailedTotal counts direct modify/scale workflow failures.
var DMModifyFailedTotal = prometheus.NewCounterVec(
	prometheus.CounterOpts{
		Namespace: DataflowNamespace,
		Subsystem: dmSubSystem,
		Name:      "modify_failed_total",
		Help:      "Total number of DM modify/scale workflow failures",
	}, []string{TenantLabel, ClusterIDLabel, jobIDLabel, StepLabel, ReasonClassLabel})

func incDMCounter(counter *prometheus.CounterVec, dfJob *entity.DFJob, stepOrStage, reasonClass string) {
	counter.WithLabelValues(
		fmt.Sprintf("%d", dfJob.TenantID),
		fmt.Sprintf("%d", dfJob.ClusterID),
		fmt.Sprintf("%d", dfJob.ID),
		stepOrStage,
		reasonClass,
	).Inc()
}

// IncDMCreateStageFailure increments the create-stage failure counter.
func IncDMCreateStageFailure(dfJob *entity.DFJob, stage, reasonClass string) {
	incDMCounter(DMCreateStageFailedTotal, dfJob, stage, reasonClass)
}

// IncDMModifyFailure increments the modify failure counter.
func IncDMModifyFailure(dfJob *entity.DFJob, step, reasonClass string) {
	incDMCounter(DMModifyFailedTotal, dfJob, step, reasonClass)
}
