package resources

import (
	"encoding/json"
	"math"
	"strconv"

	"github.com/prometheus/client_golang/prometheus"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime/schema"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/infra-provider/pkg/consts"
)

var (
	workflowGVR = schema.GroupVersionResource{
		Group:    "cloud.pingcap.com",
		Version:  "v1",
		Resource: "workflows",
	}

	workflowInfo = prometheus.NewDesc(
		prometheus.BuildFQName("infra", "exporter", "workflow"),
		"Information about Workflow CR. Its value is the progress of the workflow. 100 means completed.",
		[]string{
			"namespace",
			"name",
			"workflow_type",
			"tenant_id",
			"project_id",
			"cluster_id",
			"phase",
			"paused",
		}, nil)
)

type workflow struct {
	defaultResource
}

var _ Interface = &workflow{}

func (uo workflow) HasDedicatedLabel() bool {
	return false
}

func (uo workflow) GVR() schema.GroupVersionResource {
	return workflowGVR
}

func (uo workflow) Desc() *prometheus.Desc {
	return workflowInfo
}

func (uo workflow) FilterOut(_ *unstructured.Unstructured) bool { return false }

func (uo workflow) Extract(obj *unstructured.Unstructured) prometheus.Metric {
	bytes, _ := obj.MarshalJSON()

	var workflowCR cloudv1.Workflow
	_ = json.Unmarshal(bytes, &workflowCR)

	var progress float64
	if len(workflowCR.Spec.Steps) == 0 {
		progress = 100
	} else {
		progress = math.Ceil(float64(len(workflowCR.Status.FinishedSteps)) / float64(len(workflowCR.Spec.Steps)) * 100)
	}
	return prometheus.MustNewConstMetric(
		workflowInfo,
		prometheus.GaugeValue,
		progress,
		workflowCR.Namespace,
		workflowCR.Name,
		string(workflowCR.Spec.Type),
		workflowCR.Labels[consts.TenantLabelKey],
		workflowCR.Labels[consts.ProjectLabelKey],
		workflowCR.Labels[consts.ClusterLabelKey],
		string(workflowCR.Status.Phase),
		strconv.FormatBool(workflowCR.Spec.Paused),
	)
}
