package e2eutil

import (
	"log"
	"math"
	"time"
)

func Backoff(iteration int) time.Duration {
	return time.Duration(math.Pow(float64(2), float64(iteration))) * time.Second
}

// RetryBackoff attempts a call up to maxRetries times with increasing backoffs.
func RetryBackoff(opName string, maxRetries int, f func() error) error {
	for n := 1; n <= maxRetries; n++ {
		err := f()
		if err == nil {
			return nil
		} else if n == maxRetries {
			log.Printf("%s exceeded max retries; last failure %s", opName, err.Error())
			return err
		} else {
			duration := Backoff(n - 1)
			log.Printf("%s attempt %d/%d failed with %s; trying again in %s", opName, n, maxRetries, err.Error(), duration.String())
			time.Sleep(duration)
		}
	}
	// probably unreachable but needed to compile
	return nil
}
