package resources

import (
	"encoding/json"

	ec2v1alpha1 "github.com/crossplane-contrib/provider-aws/apis/ec2/v1alpha1"
	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 (
	vpcendpointGVR = schema.GroupVersionResource{
		Group:    "ec2.aws.crossplane.io",
		Version:  "v1alpha1",
		Resource: "vpcendpoints",
	}

	vpcEndpointInfo = prometheus.NewDesc(
		prometheus.BuildFQName("infra", "exporter", "vpcendpoint"),
		"Information about vpcendpoint CR.",
		[]string{
			"name",
			"vpcndpoint_type",
			"vpc_id",
			"region",
			"status",
			"ready",
			"synced",
		}, nil)
)

type vpcendpoint struct {
	defaultResource
}

var _ Interface = &vpcendpoint{}

func (v vpcendpoint) HasDedicatedLabel() bool {
	return false
}

func (v vpcendpoint) GVR() schema.GroupVersionResource {
	return vpcendpointGVR
}

func (v vpcendpoint) Desc() *prometheus.Desc {
	return vpcEndpointInfo
}

func (v vpcendpoint) FilterOut(_ *unstructured.Unstructured) bool {
	return false
}

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

	var endpoint ec2v1alpha1.VPCEndpoint
	_ = json.Unmarshal(bytes, &endpoint)

	var ready, synced string

	// find conditions
	for _, c := range endpoint.Status.Conditions {
		if c.Type == commonv1.TypeReady {
			ready = string(c.Status)
		}
		if c.Type == commonv1.TypeSynced {
			synced = string(c.Status)
		}
	}
	return prometheus.MustNewConstMetric(
		vpcEndpointInfo,
		prometheus.GaugeValue,
		1.0,
		endpoint.Name,
		utils.GetReferencedOrDefault(endpoint.Spec.ForProvider.VPCEndpointType, ""),
		utils.GetReferencedOrDefault(endpoint.Spec.ForProvider.VPCID, ""),
		endpoint.Spec.ForProvider.Region,
		utils.GetReferencedOrDefault(endpoint.Status.AtProvider.State, ""),
		ready,
		synced,
	)
}
