// Code generated by pkg/config/schema/codegen/tools/collections.main.go. DO NOT EDIT.

package {{.PackageName}}

import (
	"fmt"
	"context"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"

	"istio.io/istio/pkg/config"
	"istio.io/istio/pkg/config/schema/gvk"
	"istio.io/istio/pkg/kube"

	apiistioioapiextensionsv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1"
	apiistioioapinetworkingv1 "istio.io/client-go/pkg/apis/networking/v1"
	apiistioioapinetworkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
	apiistioioapinetworkingv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
	apiistioioapisecurityv1 "istio.io/client-go/pkg/apis/security/v1"
	apiistioioapitelemetryv1alpha1 "istio.io/client-go/pkg/apis/telemetry/v1alpha1"
	apiistioioapitelemetryv1 "istio.io/client-go/pkg/apis/telemetry/v1"
{{- range .Packages}}
	{{.ImportName}} "{{.PackageName}}"
{{- end}}
)

func create(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta) (metav1.Object, error) {
	switch cfg.GroupVersionKind {
{{- range .Entries }}
	{{- if and (not .Resource.Synthetic) (not .Resource.Builtin) }}
	case gvk.{{.Resource.Identifier}}:
		return c.{{.ClientGetter}}().{{ .ClientGroupPath }}().{{ .ClientTypePath }}({{if not .Resource.ClusterScoped}}cfg.Namespace{{end}}).Create(context.TODO(), &{{ .IstioAwareClientImport }}.{{ .Resource.Kind }}{
			ObjectMeta: objMeta,
			Spec:       *(cfg.Spec.(*{{ .ClientImport }}.{{.SpecType}})),
		}, metav1.CreateOptions{})
	{{- end }}
{{- end }}
	default:
		return nil, fmt.Errorf("unsupported type: %v", cfg.GroupVersionKind)
	}
}

func update(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta) (metav1.Object, error) {
	switch cfg.GroupVersionKind {
{{- range .Entries }}
	{{- if and (not .Resource.Synthetic) (not .Resource.Builtin) }}
	case gvk.{{.Resource.Identifier}}:
		return c.{{.ClientGetter}}().{{ .ClientGroupPath }}().{{ .ClientTypePath }}({{if not .Resource.ClusterScoped}}cfg.Namespace{{end}}).Update(context.TODO(), &{{ .IstioAwareClientImport }}.{{ .Resource.Kind }}{
			ObjectMeta: objMeta,
			Spec:       *(cfg.Spec.(*{{ .ClientImport }}.{{.SpecType}})),
		}, metav1.UpdateOptions{})
	{{- end }}
{{- end }}
	default:
		return nil, fmt.Errorf("unsupported type: %v", cfg.GroupVersionKind)
	}
}

func updateStatus(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta) (metav1.Object, error) {
	switch cfg.GroupVersionKind {
{{- range .Entries }}
	{{- if and (not .Resource.Synthetic) (or (not .Resource.Builtin) (eq .Resource.Identifier "Ingress")) (not (eq .StatusType "")) }}
	case gvk.{{.Resource.Identifier}}:
		return c.{{.ClientGetter}}().{{ .ClientGroupPath }}().{{ .ClientTypePath }}({{if not .Resource.ClusterScoped}}cfg.Namespace{{end}}).UpdateStatus(context.TODO(), &{{ .IstioAwareClientImport }}.{{ .Resource.Kind }}{
			ObjectMeta: objMeta,
			Status:       *(cfg.Status.(*{{ .StatusImport }}.{{.StatusType}})),
		}, metav1.UpdateOptions{})
	{{- end }}
{{- end }}
	default:
		return nil, fmt.Errorf("unsupported type: %v", cfg.GroupVersionKind)
	}
}

func patch(c kube.Client, orig config.Config, origMeta metav1.ObjectMeta, mod config.Config, modMeta metav1.ObjectMeta, typ types.PatchType) (metav1.Object, error) {
	if orig.GroupVersionKind != mod.GroupVersionKind {
		return nil, fmt.Errorf("gvk mismatch: %v, modified: %v", orig.GroupVersionKind, mod.GroupVersionKind)
	}
	switch orig.GroupVersionKind {
{{- range .Entries }}
	{{- if and (not .Resource.Synthetic) (not .Resource.Builtin) }}
	case gvk.{{.Resource.Identifier}}:
		oldRes := &{{ .IstioAwareClientImport }}.{{ .Resource.Kind }}{
				ObjectMeta: origMeta,
				Spec:       *(orig.Spec.(*{{ .ClientImport }}.{{.SpecType}})),
		}
		modRes := &{{ .IstioAwareClientImport }}.{{ .Resource.Kind }}{
			ObjectMeta: modMeta,
			Spec:       *(mod.Spec.(*{{ .ClientImport }}.{{.SpecType}})),
		}
		patchBytes, err := genPatchBytes(oldRes, modRes, typ)
		if err != nil {
				return nil, err
		}
		return c.{{.ClientGetter}}().{{ .ClientGroupPath }}().{{ .ClientTypePath }}({{if not .Resource.ClusterScoped}}orig.Namespace{{end}}).
				Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "pilot-discovery"})
	{{- end }}
{{- end }}
	default:
		return nil, fmt.Errorf("unsupported type: %v", orig.GroupVersionKind)
	}
}


func delete(c kube.Client, typ config.GroupVersionKind, name, namespace string, resourceVersion *string) error {
	var deleteOptions metav1.DeleteOptions
	if resourceVersion != nil {
		deleteOptions.Preconditions = &metav1.Preconditions{ResourceVersion: resourceVersion}
	}
	switch typ {
{{- range .Entries }}
	{{- if and (not .Resource.Synthetic) (not .Resource.Builtin) }}
	case gvk.{{.Resource.Identifier}}:
		return c.{{.ClientGetter}}().{{ .ClientGroupPath }}().{{ .ClientTypePath }}({{if not .Resource.ClusterScoped}}namespace{{end}}).Delete(context.TODO(), name, deleteOptions)
	{{- end }}
{{- end }}
	default:
		return fmt.Errorf("unsupported type: %v", typ)
	}
}


var translationMap = map[config.GroupVersionKind]func(r runtime.Object) config.Config{
{{- range .Entries }}
	{{- if and (not .Resource.Synthetic) }}
	gvk.{{.Resource.Identifier}}: func(r runtime.Object) config.Config {
		obj := r.(*{{ .IstioAwareClientImport }}.{{.Resource.Kind}})
		return config.Config{
		  Meta: config.Meta{
		  	GroupVersionKind:  gvk.{{.Resource.Identifier}},
		  	Name:              obj.Name,
		  	Namespace:         obj.Namespace,
		  	Labels:            obj.Labels,
		  	Annotations:       obj.Annotations,
		  	ResourceVersion:   obj.ResourceVersion,
		  	CreationTimestamp: obj.CreationTimestamp.Time,
		  	OwnerReferences:   obj.OwnerReferences,
		  	UID:               string(obj.UID),
		  	Generation:        obj.Generation,
		  },
			Spec:   {{ if not .Resource.Specless }}&obj.Spec{{ else }}obj{{ end }},
      {{- if not (eq .StatusType "") }}
		  Status: &obj.Status,
      {{- end }}
		}
	},
	{{- end }}
{{- end }}
}
