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

import (
	storage "github.com/Azure/azure-service-operator/v2/api/apimanagement/v1api20240501/storage"
	"github.com/Azure/azure-service-operator/v2/pkg/genruntime"
	"github.com/rotisserie/eris"
)

// Storage version of v1api20230501preview.BackendCircuitBreaker
// The configuration of the backend circuit breaker
type BackendCircuitBreaker struct {
	PropertyBag genruntime.PropertyBag `json:"$propertyBag,omitempty"`
	Rules       []CircuitBreakerRule   `json:"rules,omitempty"`
}

// AssignProperties_From_BackendCircuitBreaker populates our BackendCircuitBreaker from the provided source BackendCircuitBreaker
func (breaker *BackendCircuitBreaker) AssignProperties_From_BackendCircuitBreaker(source *storage.BackendCircuitBreaker) error {
	// Clone the existing property bag
	propertyBag := genruntime.NewPropertyBag(source.PropertyBag)

	// Rules
	if source.Rules != nil {
		ruleList := make([]CircuitBreakerRule, len(source.Rules))
		for ruleIndex, ruleItem := range source.Rules {
			var rule CircuitBreakerRule
			err := rule.AssignProperties_From_CircuitBreakerRule(&ruleItem)
			if err != nil {
				return eris.Wrap(err, "calling AssignProperties_From_CircuitBreakerRule() to populate field Rules")
			}
			ruleList[ruleIndex] = rule
		}
		breaker.Rules = ruleList
	} else {
		breaker.Rules = nil
	}

	// Update the property bag
	if len(propertyBag) > 0 {
		breaker.PropertyBag = propertyBag
	} else {
		breaker.PropertyBag = nil
	}

	// Invoke the augmentConversionForBackendCircuitBreaker interface (if implemented) to customize the conversion
	var breakerAsAny any = breaker
	if augmentedBreaker, ok := breakerAsAny.(augmentConversionForBackendCircuitBreaker); ok {
		err := augmentedBreaker.AssignPropertiesFrom(source)
		if err != nil {
			return eris.Wrap(err, "calling augmented AssignPropertiesFrom() for conversion")
		}
	}

	// No error
	return nil
}

// AssignProperties_To_BackendCircuitBreaker populates the provided destination BackendCircuitBreaker from our BackendCircuitBreaker
func (breaker *BackendCircuitBreaker) AssignProperties_To_BackendCircuitBreaker(destination *storage.BackendCircuitBreaker) error {
	// Clone the existing property bag
	propertyBag := genruntime.NewPropertyBag(breaker.PropertyBag)

	// Rules
	if breaker.Rules != nil {
		ruleList := make([]storage.CircuitBreakerRule, len(breaker.Rules))
		for ruleIndex, ruleItem := range breaker.Rules {
			var rule storage.CircuitBreakerRule
			err := ruleItem.AssignProperties_To_CircuitBreakerRule(&rule)
			if err != nil {
				return eris.Wrap(err, "calling AssignProperties_To_CircuitBreakerRule() to populate field Rules")
			}
			ruleList[ruleIndex] = rule
		}
		destination.Rules = ruleList
	} else {
		destination.Rules = nil
	}

	// Update the property bag
	if len(propertyBag) > 0 {
		destination.PropertyBag = propertyBag
	} else {
		destination.PropertyBag = nil
	}

	// Invoke the augmentConversionForBackendCircuitBreaker interface (if implemented) to customize the conversion
	var breakerAsAny any = breaker
	if augmentedBreaker, ok := breakerAsAny.(augmentConversionForBackendCircuitBreaker); ok {
		err := augmentedBreaker.AssignPropertiesTo(destination)
		if err != nil {
			return eris.Wrap(err, "calling augmented AssignPropertiesTo() for conversion")
		}
	}

	// No error
	return nil
}

type augmentConversionForBackendCircuitBreaker interface {
	AssignPropertiesFrom(src *storage.BackendCircuitBreaker) error
	AssignPropertiesTo(dst *storage.BackendCircuitBreaker) error
}

// Storage version of v1api20230501preview.CircuitBreakerRule
// Rule configuration to trip the backend.
type CircuitBreakerRule struct {
	FailureCondition *CircuitBreakerFailureCondition `json:"failureCondition,omitempty"`
	Name             *string                         `json:"name,omitempty"`
	PropertyBag      genruntime.PropertyBag          `json:"$propertyBag,omitempty"`
	TripDuration     *string                         `json:"tripDuration,omitempty"`
}

// AssignProperties_From_CircuitBreakerRule populates our CircuitBreakerRule from the provided source CircuitBreakerRule
func (rule *CircuitBreakerRule) AssignProperties_From_CircuitBreakerRule(source *storage.CircuitBreakerRule) error {
	// Clone the existing property bag
	propertyBag := genruntime.NewPropertyBag(source.PropertyBag)

	// AcceptRetryAfter
	if source.AcceptRetryAfter != nil {
		propertyBag.Add("AcceptRetryAfter", *source.AcceptRetryAfter)
	} else {
		propertyBag.Remove("AcceptRetryAfter")
	}

	// FailureCondition
	if source.FailureCondition != nil {
		var failureCondition CircuitBreakerFailureCondition
		err := failureCondition.AssignProperties_From_CircuitBreakerFailureCondition(source.FailureCondition)
		if err != nil {
			return eris.Wrap(err, "calling AssignProperties_From_CircuitBreakerFailureCondition() to populate field FailureCondition")
		}
		rule.FailureCondition = &failureCondition
	} else {
		rule.FailureCondition = nil
	}

	// Name
	rule.Name = genruntime.ClonePointerToString(source.Name)

	// TripDuration
	rule.TripDuration = genruntime.ClonePointerToString(source.TripDuration)

	// Update the property bag
	if len(propertyBag) > 0 {
		rule.PropertyBag = propertyBag
	} else {
		rule.PropertyBag = nil
	}

	// Invoke the augmentConversionForCircuitBreakerRule interface (if implemented) to customize the conversion
	var ruleAsAny any = rule
	if augmentedRule, ok := ruleAsAny.(augmentConversionForCircuitBreakerRule); ok {
		err := augmentedRule.AssignPropertiesFrom(source)
		if err != nil {
			return eris.Wrap(err, "calling augmented AssignPropertiesFrom() for conversion")
		}
	}

	// No error
	return nil
}

// AssignProperties_To_CircuitBreakerRule populates the provided destination CircuitBreakerRule from our CircuitBreakerRule
func (rule *CircuitBreakerRule) AssignProperties_To_CircuitBreakerRule(destination *storage.CircuitBreakerRule) error {
	// Clone the existing property bag
	propertyBag := genruntime.NewPropertyBag(rule.PropertyBag)

	// AcceptRetryAfter
	if propertyBag.Contains("AcceptRetryAfter") {
		var acceptRetryAfter bool
		err := propertyBag.Pull("AcceptRetryAfter", &acceptRetryAfter)
		if err != nil {
			return eris.Wrap(err, "pulling 'AcceptRetryAfter' from propertyBag")
		}

		destination.AcceptRetryAfter = &acceptRetryAfter
	} else {
		destination.AcceptRetryAfter = nil
	}

	// FailureCondition
	if rule.FailureCondition != nil {
		var failureCondition storage.CircuitBreakerFailureCondition
		err := rule.FailureCondition.AssignProperties_To_CircuitBreakerFailureCondition(&failureCondition)
		if err != nil {
			return eris.Wrap(err, "calling AssignProperties_To_CircuitBreakerFailureCondition() to populate field FailureCondition")
		}
		destination.FailureCondition = &failureCondition
	} else {
		destination.FailureCondition = nil
	}

	// Name
	destination.Name = genruntime.ClonePointerToString(rule.Name)

	// TripDuration
	destination.TripDuration = genruntime.ClonePointerToString(rule.TripDuration)

	// Update the property bag
	if len(propertyBag) > 0 {
		destination.PropertyBag = propertyBag
	} else {
		destination.PropertyBag = nil
	}

	// Invoke the augmentConversionForCircuitBreakerRule interface (if implemented) to customize the conversion
	var ruleAsAny any = rule
	if augmentedRule, ok := ruleAsAny.(augmentConversionForCircuitBreakerRule); ok {
		err := augmentedRule.AssignPropertiesTo(destination)
		if err != nil {
			return eris.Wrap(err, "calling augmented AssignPropertiesTo() for conversion")
		}
	}

	// No error
	return nil
}

type augmentConversionForCircuitBreakerRule interface {
	AssignPropertiesFrom(src *storage.CircuitBreakerRule) error
	AssignPropertiesTo(dst *storage.CircuitBreakerRule) error
}

// Storage version of v1api20230501preview.CircuitBreakerFailureCondition
// The trip conditions of the circuit breaker
type CircuitBreakerFailureCondition struct {
	Count            *int                     `json:"count,omitempty"`
	ErrorReasons     []string                 `json:"errorReasons,omitempty"`
	Interval         *string                  `json:"interval,omitempty"`
	Percentage       *int                     `json:"percentage,omitempty"`
	PropertyBag      genruntime.PropertyBag   `json:"$propertyBag,omitempty"`
	StatusCodeRanges []FailureStatusCodeRange `json:"statusCodeRanges,omitempty"`
}

// AssignProperties_From_CircuitBreakerFailureCondition populates our CircuitBreakerFailureCondition from the provided source CircuitBreakerFailureCondition
func (condition *CircuitBreakerFailureCondition) AssignProperties_From_CircuitBreakerFailureCondition(source *storage.CircuitBreakerFailureCondition) error {
	// Clone the existing property bag
	propertyBag := genruntime.NewPropertyBag(source.PropertyBag)

	// Count
	condition.Count = genruntime.ClonePointerToInt(source.Count)

	// ErrorReasons
	condition.ErrorReasons = genruntime.CloneSliceOfString(source.ErrorReasons)

	// Interval
	condition.Interval = genruntime.ClonePointerToString(source.Interval)

	// Percentage
	condition.Percentage = genruntime.ClonePointerToInt(source.Percentage)

	// StatusCodeRanges
	if source.StatusCodeRanges != nil {
		statusCodeRangeList := make([]FailureStatusCodeRange, len(source.StatusCodeRanges))
		for statusCodeRangeIndex, statusCodeRangeItem := range source.StatusCodeRanges {
			var statusCodeRange FailureStatusCodeRange
			err := statusCodeRange.AssignProperties_From_FailureStatusCodeRange(&statusCodeRangeItem)
			if err != nil {
				return eris.Wrap(err, "calling AssignProperties_From_FailureStatusCodeRange() to populate field StatusCodeRanges")
			}
			statusCodeRangeList[statusCodeRangeIndex] = statusCodeRange
		}
		condition.StatusCodeRanges = statusCodeRangeList
	} else {
		condition.StatusCodeRanges = nil
	}

	// Update the property bag
	if len(propertyBag) > 0 {
		condition.PropertyBag = propertyBag
	} else {
		condition.PropertyBag = nil
	}

	// Invoke the augmentConversionForCircuitBreakerFailureCondition interface (if implemented) to customize the conversion
	var conditionAsAny any = condition
	if augmentedCondition, ok := conditionAsAny.(augmentConversionForCircuitBreakerFailureCondition); ok {
		err := augmentedCondition.AssignPropertiesFrom(source)
		if err != nil {
			return eris.Wrap(err, "calling augmented AssignPropertiesFrom() for conversion")
		}
	}

	// No error
	return nil
}

// AssignProperties_To_CircuitBreakerFailureCondition populates the provided destination CircuitBreakerFailureCondition from our CircuitBreakerFailureCondition
func (condition *CircuitBreakerFailureCondition) AssignProperties_To_CircuitBreakerFailureCondition(destination *storage.CircuitBreakerFailureCondition) error {
	// Clone the existing property bag
	propertyBag := genruntime.NewPropertyBag(condition.PropertyBag)

	// Count
	destination.Count = genruntime.ClonePointerToInt(condition.Count)

	// ErrorReasons
	destination.ErrorReasons = genruntime.CloneSliceOfString(condition.ErrorReasons)

	// Interval
	destination.Interval = genruntime.ClonePointerToString(condition.Interval)

	// Percentage
	destination.Percentage = genruntime.ClonePointerToInt(condition.Percentage)

	// StatusCodeRanges
	if condition.StatusCodeRanges != nil {
		statusCodeRangeList := make([]storage.FailureStatusCodeRange, len(condition.StatusCodeRanges))
		for statusCodeRangeIndex, statusCodeRangeItem := range condition.StatusCodeRanges {
			var statusCodeRange storage.FailureStatusCodeRange
			err := statusCodeRangeItem.AssignProperties_To_FailureStatusCodeRange(&statusCodeRange)
			if err != nil {
				return eris.Wrap(err, "calling AssignProperties_To_FailureStatusCodeRange() to populate field StatusCodeRanges")
			}
			statusCodeRangeList[statusCodeRangeIndex] = statusCodeRange
		}
		destination.StatusCodeRanges = statusCodeRangeList
	} else {
		destination.StatusCodeRanges = nil
	}

	// Update the property bag
	if len(propertyBag) > 0 {
		destination.PropertyBag = propertyBag
	} else {
		destination.PropertyBag = nil
	}

	// Invoke the augmentConversionForCircuitBreakerFailureCondition interface (if implemented) to customize the conversion
	var conditionAsAny any = condition
	if augmentedCondition, ok := conditionAsAny.(augmentConversionForCircuitBreakerFailureCondition); ok {
		err := augmentedCondition.AssignPropertiesTo(destination)
		if err != nil {
			return eris.Wrap(err, "calling augmented AssignPropertiesTo() for conversion")
		}
	}

	// No error
	return nil
}

type augmentConversionForCircuitBreakerFailureCondition interface {
	AssignPropertiesFrom(src *storage.CircuitBreakerFailureCondition) error
	AssignPropertiesTo(dst *storage.CircuitBreakerFailureCondition) error
}

// Storage version of v1api20230501preview.FailureStatusCodeRange
// The failure http status code range
type FailureStatusCodeRange struct {
	Max         *int                   `json:"max,omitempty"`
	Min         *int                   `json:"min,omitempty"`
	PropertyBag genruntime.PropertyBag `json:"$propertyBag,omitempty"`
}

// AssignProperties_From_FailureStatusCodeRange populates our FailureStatusCodeRange from the provided source FailureStatusCodeRange
func (codeRange *FailureStatusCodeRange) AssignProperties_From_FailureStatusCodeRange(source *storage.FailureStatusCodeRange) error {
	// Clone the existing property bag
	propertyBag := genruntime.NewPropertyBag(source.PropertyBag)

	// Max
	codeRange.Max = genruntime.ClonePointerToInt(source.Max)

	// Min
	codeRange.Min = genruntime.ClonePointerToInt(source.Min)

	// Update the property bag
	if len(propertyBag) > 0 {
		codeRange.PropertyBag = propertyBag
	} else {
		codeRange.PropertyBag = nil
	}

	// Invoke the augmentConversionForFailureStatusCodeRange interface (if implemented) to customize the conversion
	var codeRangeAsAny any = codeRange
	if augmentedCodeRange, ok := codeRangeAsAny.(augmentConversionForFailureStatusCodeRange); ok {
		err := augmentedCodeRange.AssignPropertiesFrom(source)
		if err != nil {
			return eris.Wrap(err, "calling augmented AssignPropertiesFrom() for conversion")
		}
	}

	// No error
	return nil
}

// AssignProperties_To_FailureStatusCodeRange populates the provided destination FailureStatusCodeRange from our FailureStatusCodeRange
func (codeRange *FailureStatusCodeRange) AssignProperties_To_FailureStatusCodeRange(destination *storage.FailureStatusCodeRange) error {
	// Clone the existing property bag
	propertyBag := genruntime.NewPropertyBag(codeRange.PropertyBag)

	// Max
	destination.Max = genruntime.ClonePointerToInt(codeRange.Max)

	// Min
	destination.Min = genruntime.ClonePointerToInt(codeRange.Min)

	// Update the property bag
	if len(propertyBag) > 0 {
		destination.PropertyBag = propertyBag
	} else {
		destination.PropertyBag = nil
	}

	// Invoke the augmentConversionForFailureStatusCodeRange interface (if implemented) to customize the conversion
	var codeRangeAsAny any = codeRange
	if augmentedCodeRange, ok := codeRangeAsAny.(augmentConversionForFailureStatusCodeRange); ok {
		err := augmentedCodeRange.AssignPropertiesTo(destination)
		if err != nil {
			return eris.Wrap(err, "calling augmented AssignPropertiesTo() for conversion")
		}
	}

	// No error
	return nil
}

type augmentConversionForFailureStatusCodeRange interface {
	AssignPropertiesFrom(src *storage.FailureStatusCodeRange) error
	AssignPropertiesTo(dst *storage.FailureStatusCodeRange) error
}
