package resources

import (
	"encoding/json"

	"github.com/crossplane-contrib/provider-gcp/apis/container/v1beta2"
	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 (
	gkeGVR = schema.GroupVersionResource{
		Group:    "container.gcp.crossplane.io",
		Version:  "v1beta2",
		Resource: "clusters",
	}

	gkeInfo = prometheus.NewDesc(
		prometheus.BuildFQName("infra", "exporter", "gke"),
		"Information about gke CR.",
		[]string{
			"name",
			"init_version",
			"release_channel",
			"actual_version",
			"region",
			"status",
			"ready",
			"synced",
		}, nil)
)

type gke struct {
	defaultResource
}

var _ Interface = &gke{}

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

func (r gke) GVR() schema.GroupVersionResource {
	return gkeGVR
}

func (r gke) Desc() *prometheus.Desc {
	return gkeInfo
}

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

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

	var cr v1beta2.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)
		}
	}

	var releaseChannel string
	if cr.Spec.ForProvider.ReleaseChannel != nil {
		releaseChannel = cr.Spec.ForProvider.ReleaseChannel.Channel
	}

	return prometheus.MustNewConstMetric(
		gkeInfo,
		prometheus.GaugeValue,
		1.0,
		cr.Name,
		utils.GetReferencedOrDefault(cr.Spec.ForProvider.InitialClusterVersion, ""),
		releaseChannel,
		cr.Status.AtProvider.CurrentMasterVersion,
		cr.Status.AtProvider.Location,
		cr.Status.AtProvider.Status,
		ready,
		synced,
	)
}
