package backoff

import (
	"context"
	"time"
)

// ExponentialRetry ...
type ExponentialRetry struct {
	Constant time.Duration
	MaxTries int

	err   error
	tries int
}

// Try sleeps if err is not nil and returns true
func (er *ExponentialRetry) Try(ctx context.Context, err error) bool {
	er.tries++

	if err == nil {
		// success
		return false
	}

	er.err = err

	if er.MaxTries >= 0 && er.tries >= er.MaxTries {
		return false
	}

	select {
	case <-ctx.Done():
		return false
	case <-er.timer().C:
		return true
	}
}

// Err returns an error if it was encountered
func (er *ExponentialRetry) Err() error {
	return er.err
}

func (er *ExponentialRetry) timer() *time.Timer {
	return time.NewTimer(time.Duration(er.tries+1) * er.Constant)
}
