func prepareJSONValue(overlay interface{}) string {
	var err error
	overlayWithoutAnchors := removeAnchorFromSubTree(overlay)
	jsonOverlay, err := json.Marshal(overlayWithoutAnchors)
	if err != nil || hasOnlyAnchors(overlay) {
		log.Log.Error(err, "failed to marshall withoutanchors or has only anchors")
		return ""
	}
	return string(jsonOverlay)
}
converts overlay to JSON string to be inserted into the JSON Patch
package mutate
import (
	"encoding/json"
	"errors"
	"fmt"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"
	jsonpatch "github.com/evanphx/json-patch/v5"
	"github.com/go-logr/logr"
	commonAnchors "github.com/kyverno/kyverno/pkg/engine/anchor/common"
	"github.com/kyverno/kyverno/pkg/engine/common"
	"github.com/kyverno/kyverno/pkg/engine/response"
	"github.com/kyverno/kyverno/pkg/engine/utils"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"sigs.k8s.io/controller-runtime/pkg/log"
)
func ProcessOverlay(log logr.Logger, ruleName string, overlay interface{}, resource unstructured.Unstructured) (resp response.RuleResponse, patchedResource unstructured.Unstructured) {
	startTime := time.Now()
	logger := log.WithValues("rule", ruleName)
	logger.V(4).Info("started applying overlay rule", "startTime", startTime)
	resp.Name = ruleName
	resp.Type = utils.Mutation.String()
	defer func() {
		resp.RuleStats.ProcessingTime = time.Since(startTime)
		resp.RuleStats.RuleExecutionTimestamp = startTime.Unix()
		logger.V(4).Info("finished applying overlay rule", "processingTime", resp.RuleStats.ProcessingTime.String())
	}()
	patches, overlayerr := processOverlayPatches(logger, resource.UnstructuredContent(), overlay)
	if !reflect.DeepEqual(overlayerr, overlayError{}) {
		switch overlayerr.statusCode {
		case conditionNotPresent:
			logger.V(3).Info("skip applying rule", "reason", "conditionNotPresent")
			resp.Status = response.RuleStatusPass
			return resp, resource
		case conditionFailure:
			logger.V(3).Info("skip applying rule", "reason", "conditionFailure")
			resp.Status = response.RuleStatusPass
			resp.Message = overlayerr.ErrorMsg()
			return resp, resource
		case overlayFailure:
			logger.Info("failed to process overlay")
			resp.Status = response.RuleStatusFail
			resp.Message = fmt.Sprintf("failed to process overlay: %v", overlayerr.ErrorMsg())
			return resp, resource
		default:
			logger.Info("failed to process overlay")
			resp.Status = response.RuleStatusFail
			resp.Message = fmt.Sprintf("Unknown type of error: %v", overlayerr.Error())
			return resp, resource
		}
	}
	logger.V(4).Info("processing overlay rule", "patches", len(patches))
	if len(patches) == 0 {
		resp.Status = response.RuleStatusPass
		return resp, resource
	}
	resourceRaw, err := resource.MarshalJSON()
	if err != nil {
		resp.Status = response.RuleStatusFail
		logger.Error(err, "failed to marshal resource")
		resp.Message = fmt.Sprintf("failed to process JSON patches: %v", err)
		return resp, resource
	}
	var patchResource []byte
	logger.V(5).Info("applying overlay patches", "patches", string(utils.JoinPatches(patches)))
	patchResource, err = utils.ApplyPatches(resourceRaw, patches)
	if err != nil {
		msg := fmt.Sprintf("failed to apply JSON patches: %v", err)
		resp.Status = response.RuleStatusFail
		resp.Message = msg
		return resp, resource
	}
	logger.V(5).Info("patched resource", "patches", string(patchResource))
	err = patchedResource.UnmarshalJSON(patchResource)
	if err != nil {
		logger.Error(err, "failed to unmarshal resource")
		resp.Status = response.RuleStatusFail
		resp.Message = fmt.Sprintf("failed to process JSON patches: %v", err)
		return resp, resource
	}
	resp.Status = response.RuleStatusPass
	resp.Message = string("successfully processed overlay")
	resp.Patches = patches
	return resp, patchedResource
}
func processOverlayPatches(log logr.Logger, resource, overlay interface{}) ([][]byte, overlayError) {
	if path, overlayerr := meetConditions(log, resource, overlay); !reflect.DeepEqual(overlayerr, overlayError{}) {
		switch overlayerr.statusCode {
		case conditionNotPresent:
			log.V(4).Info("skip applying policy", "path", path, "error", overlayerr)
			return nil, newOverlayError(overlayerr.statusCode, fmt.Sprintf("Policy not applied, condition tag not present: %v at %s", overlayerr.ErrorMsg(), path))
		case conditionFailure:
			log.V(4).Info("failed to validate condition", "path", path, "error", overlayerr)
			return nil, newOverlayError(overlayerr.statusCode, fmt.Sprintf("Policy not applied, conditions are not met at %s, %v", path, overlayerr))
		}
	}
	patchBytes, err := MutateResourceWithOverlay(resource, overlay)
	if err != nil {
		return patchBytes, newOverlayError(overlayFailure, err.Error())
	}
	return patchBytes, overlayError{}
}
func MutateResourceWithOverlay(resource, pattern interface{}) ([][]byte, error) {
	return applyOverlay(resource, pattern, "/")
}
func applyOverlay(resource, overlay interface{}, path string) ([][]byte, error) {
	if reflect.TypeOf(resource) != reflect.TypeOf(overlay) {
		patch, err := replaceSubtree(overlay, path)
		if err != nil {
			return nil, err
		}
		return [][]byte{patch}, nil
	}
	return applyOverlayForSameTypes(resource, overlay, path)
}
func applyOverlayForSameTypes(resource, overlay interface{}, path string) ([][]byte, error) {
	var appliedPatches [][]byte
	switch typedOverlay := overlay.(type) {
	case map[string]interface{}:
		typedResource := resource.(map[string]interface{})
		patches, err := applyOverlayToMap(typedResource, typedOverlay, path)
		if err != nil {
			return nil, err
		}
		appliedPatches = append(appliedPatches, patches...)
	case []interface{}:
		typedResource := resource.([]interface{})
		patches, err := applyOverlayToArray(typedResource, typedOverlay, path)
		if err != nil {
			return nil, err
		}
		appliedPatches = append(appliedPatches, patches...)
	case string, float64, int64, bool:
		patch, err := replaceSubtree(overlay, path)
		if err != nil {
			return nil, err
		}
		appliedPatches = append(appliedPatches, patch)
	default:
		return nil, fmt.Errorf("overlay has unsupported type: %T", overlay)
	}
	return appliedPatches, nil
}
func applyOverlayToMap(resourceMap, overlayMap map[string]interface{}, path string) ([][]byte, error) {
	var appliedPatches [][]byte
	for key, value := range overlayMap {
		if commonAnchors.IsConditionAnchor(key) {
			continue
		}
		noAnchorKey := removeAnchor(key)
		currentPath := path + noAnchorKey + "/"
		resourcePart, ok := resourceMap[noAnchorKey]
		if ok && !commonAnchors.IsAddingAnchor(key) {
			patches, err := applyOverlay(resourcePart, value, currentPath)
			if err != nil {
				return nil, err
			}
			appliedPatches = append(appliedPatches, patches...)
		}
		if !ok {
			patch, err := insertSubtree(value, currentPath)
			if err != nil {
				return nil, err
			}
			appliedPatches = append(appliedPatches, patch)
		}
	}
	return appliedPatches, nil
}
func applyOverlayToArray(resource, overlay []interface{}, path string) ([][]byte, error) {
	var appliedPatches [][]byte
	if len(overlay) == 0 {
		return nil, errors.New("empty array detected in the overlay")
	}
	if len(resource) == 0 {
		patch, err := insertSubtree(overlay, path)
		if err != nil {
			return nil, err
		}
		appliedPatches = append(appliedPatches, patch)
		return appliedPatches, nil
	}
	if reflect.TypeOf(resource[0]) != reflect.TypeOf(overlay[0]) {
		return nil, fmt.Errorf("overlay array and resource array have elements of different types: %T and %T", overlay[0], resource[0])
	}
	return applyOverlayToArrayOfSameTypes(resource, overlay, path)
}
func applyOverlayToArrayOfSameTypes(resource, overlay []interface{}, path string) ([][]byte, error) {
	var appliedPatches [][]byte
	switch overlay[0].(type) {
	case map[string]interface{}:
		return applyOverlayToArrayOfMaps(resource, overlay, path)
	default:
		lastElementIdx := len(resource)
		for i, value := range overlay {
			currentPath := path + strconv.Itoa(lastElementIdx+i) + "/"
			patch, err := insertSubtree(value, currentPath)
			if err != nil {
				return nil, err
			}
			appliedPatches = append(appliedPatches, patch)
		}
	}
	return appliedPatches, nil
}
func applyOverlayToArrayOfMaps(resource, overlay []interface{}, path string) ([][]byte, error) {
	var appliedPatches [][]byte
	lastElementIdx := len(resource)
	for i, overlayElement := range overlay {
		typedOverlay := overlayElement.(map[string]interface{})
		anchors := utils.GetAnchorsFromMap(typedOverlay)
		if len(anchors) > 0 {
			patches, err := applyOverlayWithAnchors(resource, overlayElement, path)
			if err != nil {
				return nil, err
			}
			appliedPatches = append(appliedPatches, patches...)
		} else if hasNestedAnchors(overlayElement) {
			for j, resourceElement := range resource {
				currentPath := path + strconv.Itoa(j) + "/"
				patches, err := applyOverlay(resourceElement, overlayElement, currentPath)
				if err != nil {
					return nil, err
				}
				appliedPatches = append(appliedPatches, patches...)
			}
		} else {
			currentPath := path + strconv.Itoa(lastElementIdx+i) + "/"
			patch, err := insertSubtree(overlayElement, currentPath)
			if err != nil {
				return nil, err
			}
			appliedPatches = append(appliedPatches, patch)
		}
	}
	return appliedPatches, nil
}
func applyOverlayWithAnchors(resource []interface{}, overlay interface{}, path string) ([][]byte, error) {
	var appliedPatches [][]byte
	for i, resourceElement := range resource {
		currentPath := path + strconv.Itoa(i) + "/"
		patches, err := applyOverlay(resourceElement, overlay, currentPath)
		if err != nil {
			return nil, err
		}
		appliedPatches = append(appliedPatches, patches...)
	}
	return appliedPatches, nil
}
func insertSubtree(overlay interface{}, path string) ([]byte, error) {
	return processSubtree(overlay, path, "add")
}
func replaceSubtree(overlay interface{}, path string) ([]byte, error) {
	return processSubtree(overlay, path, "replace")
}
func processSubtree(overlay interface{}, path string, op string) ([]byte, error) {
	if len(path) > 1 && path[len(path)-1] == '/' {
		path = path[:len(path)-1]
	}
	path = preparePath(path)
	value := prepareJSONValue(overlay)
	patchStr := fmt.Sprintf(`{ "op": "%s", "path": "%s", "value":%s }`, op, path, value)
	if strings.Contains(path, "/metadata/annotations") ||
		strings.Contains(path, "/metadata/labels") {
		patchStr = wrapBoolean(patchStr)
	}
	_, err := jsonpatch.DecodePatch([]byte("[" + patchStr + "]"))
	if err != nil {
		return nil, fmt.Errorf("failed to make '%s' patch from an overlay '%s' for path %s, err: %v", op, value, path, err)
	}
	return []byte(patchStr), nil
}
func preparePath(path string) string {
	if path == "" {
		return "/"
	}
	path = replaceSlashes(path, "/metadata/annotations/")
	path = replaceSlashes(path, "/metadata/labels/")
	return path
}
func replaceSlashes(path, prefix string) string {
	if !strings.Contains(path, prefix) {
		return path
	}
	idx := strings.Index(path, prefix)
	p := path[idx+len(prefix):]
	path = path[:idx+len(prefix)] + strings.ReplaceAll(p, "/", "~1")
	return path
}