// Code generated by azure-service-operator-codegen. DO NOT EDIT.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
package webhook

import (
	"context"
	"fmt"
	v20240401 "github.com/Azure/azure-service-operator/v2/api/machinelearningservices/v1api20240401"
	"github.com/Azure/azure-service-operator/v2/internal/reflecthelpers"
	"github.com/Azure/azure-service-operator/v2/pkg/genruntime"
	"github.com/Azure/azure-service-operator/v2/pkg/genruntime/configmaps"
	"github.com/Azure/azure-service-operator/v2/pkg/genruntime/secrets"
	"k8s.io/apimachinery/pkg/runtime"
	"sigs.k8s.io/controller-runtime/pkg/webhook"
	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

type Registry struct {
}

// +kubebuilder:webhook:path=/mutate-machinelearningservices-azure-com-v1api20240401-registry,mutating=true,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=machinelearningservices.azure.com,resources=registries,verbs=create;update,versions=v1api20240401,name=default.v1api20240401.registries.machinelearningservices.azure.com,admissionReviewVersions=v1

var _ webhook.CustomDefaulter = &Registry{}

// Default applies defaults to the Registry resource
func (registry *Registry) Default(ctx context.Context, obj runtime.Object) error {
	resource, ok := obj.(*v20240401.Registry)
	if !ok {
		return fmt.Errorf("expected github.com/Azure/azure-service-operator/v2/api/machinelearningservices/v1api20240401/Registry, but got %T", obj)
	}
	err := registry.defaultImpl(ctx, resource)
	if err != nil {
		return err
	}
	var temp any = registry
	if runtimeDefaulter, ok := temp.(genruntime.Defaulter); ok {
		err = runtimeDefaulter.CustomDefault(ctx, resource)
		if err != nil {
			return err
		}
	}
	return nil
}

// defaultAzureName defaults the Azure name of the resource to the Kubernetes name
func (registry *Registry) defaultAzureName(ctx context.Context, obj *v20240401.Registry) error {
	if obj.Spec.AzureName == "" {
		obj.Spec.AzureName = obj.Name
	}
	return nil
}

// defaultImpl applies the code generated defaults to the Registry resource
func (registry *Registry) defaultImpl(ctx context.Context, obj *v20240401.Registry) error {
	err := registry.defaultAzureName(ctx, obj)
	if err != nil {
		return err
	}
	return nil
}

// +kubebuilder:webhook:path=/validate-machinelearningservices-azure-com-v1api20240401-registry,mutating=false,sideEffects=None,matchPolicy=Exact,failurePolicy=fail,groups=machinelearningservices.azure.com,resources=registries,verbs=create;update,versions=v1api20240401,name=validate.v1api20240401.registries.machinelearningservices.azure.com,admissionReviewVersions=v1

var _ webhook.CustomValidator = &Registry{}

// ValidateCreate validates the creation of the resource
func (registry *Registry) ValidateCreate(ctx context.Context, resource runtime.Object) (admission.Warnings, error) {
	obj, ok := resource.(*v20240401.Registry)
	if !ok {
		return nil, fmt.Errorf("expected github.com/Azure/azure-service-operator/v2/api/machinelearningservices/v1api20240401/Registry, but got %T", resource)
	}
	validations := registry.createValidations()
	var temp any = registry
	if runtimeValidator, ok := temp.(genruntime.Validator[*v20240401.Registry]); ok {
		validations = append(validations, runtimeValidator.CreateValidations()...)
	}
	return genruntime.ValidateCreate(ctx, obj, validations)
}

// ValidateDelete validates the deletion of the resource
func (registry *Registry) ValidateDelete(ctx context.Context, resource runtime.Object) (admission.Warnings, error) {
	obj, ok := resource.(*v20240401.Registry)
	if !ok {
		return nil, fmt.Errorf("expected github.com/Azure/azure-service-operator/v2/api/machinelearningservices/v1api20240401/Registry, but got %T", resource)
	}
	validations := registry.deleteValidations()
	var temp any = registry
	if runtimeValidator, ok := temp.(genruntime.Validator[*v20240401.Registry]); ok {
		validations = append(validations, runtimeValidator.DeleteValidations()...)
	}
	return genruntime.ValidateDelete(ctx, obj, validations)
}

// ValidateUpdate validates an update of the resource
func (registry *Registry) ValidateUpdate(ctx context.Context, oldResource runtime.Object, newResource runtime.Object) (admission.Warnings, error) {
	newObj, ok := newResource.(*v20240401.Registry)
	if !ok {
		return nil, fmt.Errorf("expected github.com/Azure/azure-service-operator/v2/api/machinelearningservices/v1api20240401/Registry, but got %T", newResource)
	}
	oldObj, ok := oldResource.(*v20240401.Registry)
	if !ok {
		return nil, fmt.Errorf("expected github.com/Azure/azure-service-operator/v2/api/machinelearningservices/v1api20240401/Registry, but got %T", oldResource)
	}
	validations := registry.updateValidations()
	var temp any = registry
	if runtimeValidator, ok := temp.(genruntime.Validator[*v20240401.Registry]); ok {
		validations = append(validations, runtimeValidator.UpdateValidations()...)
	}
	return genruntime.ValidateUpdate(
		ctx,
		oldObj,
		newObj,
		validations)
}

// createValidations validates the creation of the resource
func (registry *Registry) createValidations() []func(ctx context.Context, obj *v20240401.Registry) (admission.Warnings, error) {
	return []func(ctx context.Context, obj *v20240401.Registry) (admission.Warnings, error){
		registry.validateResourceReferences,
		registry.validateOwnerReference,
		registry.validateSecretDestinations,
		registry.validateConfigMapDestinations,
	}
}

// deleteValidations validates the deletion of the resource
func (registry *Registry) deleteValidations() []func(ctx context.Context, obj *v20240401.Registry) (admission.Warnings, error) {
	return nil
}

// updateValidations validates the update of the resource
func (registry *Registry) updateValidations() []func(ctx context.Context, oldObj *v20240401.Registry, newObj *v20240401.Registry) (admission.Warnings, error) {
	return []func(ctx context.Context, oldObj *v20240401.Registry, newObj *v20240401.Registry) (admission.Warnings, error){
		func(ctx context.Context, oldObj *v20240401.Registry, newObj *v20240401.Registry) (admission.Warnings, error) {
			return registry.validateResourceReferences(ctx, newObj)
		},
		registry.validateWriteOnceProperties,
		func(ctx context.Context, oldObj *v20240401.Registry, newObj *v20240401.Registry) (admission.Warnings, error) {
			return registry.validateOwnerReference(ctx, newObj)
		},
		func(ctx context.Context, oldObj *v20240401.Registry, newObj *v20240401.Registry) (admission.Warnings, error) {
			return registry.validateSecretDestinations(ctx, newObj)
		},
		func(ctx context.Context, oldObj *v20240401.Registry, newObj *v20240401.Registry) (admission.Warnings, error) {
			return registry.validateConfigMapDestinations(ctx, newObj)
		},
	}
}

// validateConfigMapDestinations validates there are no colliding genruntime.ConfigMapDestinations
func (registry *Registry) validateConfigMapDestinations(ctx context.Context, obj *v20240401.Registry) (admission.Warnings, error) {
	if obj.Spec.OperatorSpec == nil {
		return nil, nil
	}
	var toValidate []*genruntime.ConfigMapDestination
	if obj.Spec.OperatorSpec.ConfigMaps != nil {
		toValidate = []*genruntime.ConfigMapDestination{
			obj.Spec.OperatorSpec.ConfigMaps.DiscoveryUrl,
			obj.Spec.OperatorSpec.ConfigMaps.MlFlowRegistryUri,
		}
	}
	return configmaps.ValidateDestinations(obj, toValidate, obj.Spec.OperatorSpec.ConfigMapExpressions)
}

// validateOwnerReference validates the owner field
func (registry *Registry) validateOwnerReference(ctx context.Context, obj *v20240401.Registry) (admission.Warnings, error) {
	return genruntime.ValidateOwner(obj)
}

// validateResourceReferences validates all resource references
func (registry *Registry) validateResourceReferences(ctx context.Context, obj *v20240401.Registry) (admission.Warnings, error) {
	refs, err := reflecthelpers.FindResourceReferences(&obj.Spec)
	if err != nil {
		return nil, err
	}
	return genruntime.ValidateResourceReferences(refs)
}

// validateSecretDestinations validates there are no colliding genruntime.SecretDestination's
func (registry *Registry) validateSecretDestinations(ctx context.Context, obj *v20240401.Registry) (admission.Warnings, error) {
	if obj.Spec.OperatorSpec == nil {
		return nil, nil
	}
	return secrets.ValidateDestinations(obj, nil, obj.Spec.OperatorSpec.SecretExpressions)
}

// validateWriteOnceProperties validates all WriteOnce properties
func (registry *Registry) validateWriteOnceProperties(ctx context.Context, oldObj *v20240401.Registry, newObj *v20240401.Registry) (admission.Warnings, error) {
	return genruntime.ValidateWriteOnceProperties(oldObj, newObj)
}
