package resources

import (
	"encoding/json"

	"github.com/crossplane-contrib/provider-aws/apis/eks/v1beta1"
	commonv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
	"github.com/prometheus/client_golang/prometheus"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime/schema"

	"github.com/tidbcloud/eks-provider/infra-exporter/utils"
)

var (
	eksGVR = schema.GroupVersionResource{
		Group:    "eks.aws.crossplane.io",
		Version:  "v1beta1",
		Resource: "clusters",
	}

	eksInfo = prometheus.NewDesc(
		prometheus.BuildFQName("infra", "exporter", "eks"),
		"Information about eks CR.",
		[]string{
			"name",
			"desired_version",
			"actual_version",
			"status",
			"ready",
			"synced",
		}, nil)
)

type eks struct {
	defaultResource
}

var _ Interface = &eks{}

func (r eks) HasDedicatedLabel() bool {
	return false
}

func (r eks) GVR() schema.GroupVersionResource {
	return eksGVR
}

func (r eks) Desc() *prometheus.Desc {
	return eksInfo
}

func (r eks) FilterOut(_ *unstructured.Unstructured) bool {
	return false
}

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

	var cr v1beta1.Cluster
	_ = json.Unmarshal(bytes, &cr)

	var ready, synced string

	for _, c := range cr.Status.Conditions {
		if c.Type == commonv1.TypeReady {
			ready = string(c.Status)
		}
		if c.Type == commonv1.TypeSynced {
			synced = string(c.Status)
		}
	}

	return prometheus.MustNewConstMetric(
		eksInfo,
		prometheus.GaugeValue,
		1.0,
		cr.Name,
		utils.GetReferencedOrDefault(cr.Spec.ForProvider.Version, ""),
		cr.Status.AtProvider.Version,
		string(cr.Status.AtProvider.Status),
		ready,
		synced,
	)
}
