// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package retry

import (
	"math"
	"math/rand"
	"time"
)

// Stop indicates that no more retries should be made.
const Stop time.Duration = -1

type Backoff interface {
	// Next gets the duration to wait before retrying the operation or |Stop|
	// to indicate that no retries should be made.
	Next() time.Duration

	// Reset resets to initial state.
	Reset()
}

// ZeroBackoff is a fixed policy whose back-off time is always zero, meaning
// that the operation is retried immediately without waiting.
type ZeroBackoff struct{}

func (b *ZeroBackoff) Reset() {}

func (b *ZeroBackoff) Next() time.Duration { return 0 }

// ConstantBackoff is a fixed policy that always returns the same backoff delay.
type ConstantBackoff struct {
	interval time.Duration
}

func (b *ConstantBackoff) Reset() {}

func (b *ConstantBackoff) Next() time.Duration { return b.interval }

func NewConstantBackoff(d time.Duration) *ConstantBackoff {
	return &ConstantBackoff{interval: d}
}

type maxAttemptsBackoff struct {
	backOff     Backoff
	maxAttempts uint64
	numAttempts uint64
}

func (b *maxAttemptsBackoff) Next() time.Duration {
	if b.maxAttempts > 0 {
		b.numAttempts++
		if b.numAttempts >= b.maxAttempts {
			return Stop
		}
	}
	return b.backOff.Next()
}

func (b *maxAttemptsBackoff) Reset() {
	b.numAttempts = 0
	b.backOff.Reset()
}

// WithMaxAttempts wraps a back-off which stops after |max| attempts. If the max
// is 0, then it won't apply a maximum number attempts.
func WithMaxAttempts(b Backoff, max uint64) Backoff {
	return &maxAttemptsBackoff{backOff: b, maxAttempts: max}
}

type maxDurationBackoff struct {
	backOff     Backoff
	maxDuration time.Duration
	startTime   time.Time
	c           clock
}

func (b *maxDurationBackoff) Next() time.Duration {
	if b.c.Since(b.startTime) < b.maxDuration {
		return b.backOff.Next()
	}
	return Stop
}

func (b *maxDurationBackoff) Reset() {
	b.startTime = b.c.Now()
	b.backOff.Reset()
}

// WithMaxDuration wraps a back-off which stops attempting retries after |max|
// duration.
func WithMaxDuration(b Backoff, max time.Duration) Backoff {
	return &maxDurationBackoff{backOff: b, maxDuration: max, c: &systemClock{}}
}

// ExponentialBackoff is a policy that increase the delay exponentially, with a
// small amount of randomness.
type ExponentialBackoff struct {
	initialInterval time.Duration
	maxInterval     time.Duration
	multiplier      float64
	iteration       int
	randObj         *rand.Rand
}

// NewExponentialBackoff returns a new ExponentialBackoff object.
func NewExponentialBackoff(initialInterval time.Duration, maxInterval time.Duration, multiplier float64) *ExponentialBackoff {
	return &ExponentialBackoff{
		initialInterval: initialInterval,
		maxInterval:     maxInterval,
		multiplier:      multiplier,
		iteration:       0,
		randObj:         rand.New(rand.NewSource(time.Now().UnixNano())),
	}
}

func (e *ExponentialBackoff) Reset() {
	e.iteration = 0
}

func (e *ExponentialBackoff) Next() time.Duration {
	// Number of seconds to wait for the next attempt.
	seconds := float64(e.initialInterval) / float64(time.Second) * math.Pow(e.multiplier, float64(e.iteration))
	// Plus a random interval proportional to the number of seconds, with a
	// ceiling.
	seconds += math.Min(10.0, seconds/2) * e.randObj.Float64()
	next := time.Duration(seconds * float64(time.Second))
	if next > e.maxInterval {
		return e.maxInterval
	}
	e.iteration++
	return next
}

// NoRetries returns a backoff that will do a single attempt, with no retries.
func NoRetries() Backoff {
	return WithMaxAttempts(&ZeroBackoff{}, 1)
}
