// Code generated by mdatagen. DO NOT EDIT.

package configretry

import (
	"errors"
	"time"
)

// BackOffConfig defines configuration for retrying batches in case of export failure. The current supported strategy is exponential backoff.
type BackOffConfig struct {
	// Indicates whether to not retry sending batches in case of export failure.
	Enabled bool `mapstructure:"enabled"`
	// The time to wait after the first failure before retrying.
	InitialInterval time.Duration `mapstructure:"initial_interval"`
	// The maximum amount of time (including retries) spent trying to send a request/batch. Once this value is reached, the data is discarded. If set to 0, the retries are never stopped.
	MaxElapsedTime time.Duration `mapstructure:"max_elapsed_time"`
	// The upper bound on backoff interval. Once this value is reached the delay between consecutive retries will always be `MaxInterval`.
	MaxInterval time.Duration `mapstructure:"max_interval"`
	// The value multiplied by the backoff interval bounds
	Multiplier float64 `mapstructure:"multiplier"`
	// A random factor used to calculate next backoffs Randomized interval = RetryInterval * (1 ± RandomizationFactor)
	RandomizationFactor float64 `mapstructure:"randomization_factor"`
	// prevent unkeyed literal initialization
	_ struct{}
}

// Validate validates the BackOffConfig fields according to schema annotations.
func (c *BackOffConfig) Validate() error {
	var err error

	if inner_err := validateMaxElapsedTime(c); inner_err != nil {
		err = errors.Join(err, inner_err)
	}

	if c.InitialInterval < 0 {
		err = errors.Join(err, errors.New("initial_interval value must be greater than or equal to 0"))
	}

	if c.MaxElapsedTime < 0 {
		err = errors.Join(err, errors.New("max_elapsed_time value must be greater than or equal to 0"))
	}

	if c.MaxInterval < 0 {
		err = errors.Join(err, errors.New("max_interval value must be greater than or equal to 0"))
	}

	if c.Multiplier < 0 {
		err = errors.Join(err, errors.New("multiplier value must be greater than or equal to 0"))
	}

	if c.RandomizationFactor < 0 {
		err = errors.Join(err, errors.New("randomization_factor value must be greater than or equal to 0"))
	}
	if c.RandomizationFactor > 1 {
		err = errors.Join(err, errors.New("randomization_factor value must be less than or equal to 1"))
	}

	return err
}

// NewDefaultBackOffConfig returns a new BackOffConfig with default values consistent with the annotations in the schema.
func NewDefaultBackOffConfig() BackOffConfig {
	return BackOffConfig{
		Enabled:             true,
		InitialInterval:     5 * time.Second,
		MaxElapsedTime:      5 * time.Minute,
		MaxInterval:         30 * time.Second,
		Multiplier:          1.5,
		RandomizationFactor: 0.5,
	}
}
