/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.beam.sdk.util;

import static org.apache.beam.vendor.guava.v20_0.com.google.common.base.Preconditions.checkArgument;

import org.apache.beam.vendor.guava.v20_0.com.google.common.base.MoreObjects;
import org.joda.time.Duration;

/**
 * A fluent builder for {@link BackOff} objects that allows customization of the retry algorithm.
 *
 * @see #DEFAULT for the default configuration parameters.
 */
public final class FluentBackoff {

  private static final double DEFAULT_EXPONENT = 1.5;
  private static final double DEFAULT_RANDOMIZATION_FACTOR = 0.5;
  private static final Duration DEFAULT_MIN_BACKOFF = Duration.standardSeconds(1);
  private static final Duration DEFAULT_MAX_BACKOFF = Duration.standardDays(1000);
  private static final int DEFAULT_MAX_RETRIES = Integer.MAX_VALUE;
  private static final Duration DEFAULT_MAX_CUM_BACKOFF = Duration.standardDays(1000);

  private final double exponent;
  private final Duration initialBackoff;
  private final Duration maxBackoff;
  private final Duration maxCumulativeBackoff;
  private final int maxRetries;

  /**
   * By default the {@link BackOff} created by this builder will use exponential backoff (base
   * exponent 1.5) with an initial backoff of 1 second. These parameters can be overridden with
   * {@link #withExponent(double)} and {@link #withInitialBackoff(Duration)}, respectively, and the
   * maximum backoff after exponential increase can be capped using {@link
   * FluentBackoff#withMaxBackoff(Duration)}.
   *
   * <p>The default {@link BackOff} does not limit the number of retries. To limit the backoff, the
   * maximum total number of retries can be set using {@link #withMaxRetries(int)}. The total time
   * spent in backoff can be time-bounded as well by configuring {@link
   * #withMaxCumulativeBackoff(Duration)}. If either of these limits are reached, calls to {@link
   * BackOff#nextBackOffMillis()} will return {@link BackOff#STOP} to signal that no more retries
   * should continue.
   */
  public static final FluentBackoff DEFAULT =
      new FluentBackoff(
          DEFAULT_EXPONENT,
          DEFAULT_MIN_BACKOFF,
          DEFAULT_MAX_BACKOFF,
          DEFAULT_MAX_CUM_BACKOFF,
          DEFAULT_MAX_RETRIES);

  /**
   * Instantiates a {@link BackOff} that will obey the current configuration.
   *
   * @see FluentBackoff
   */
  public BackOff backoff() {
    return new BackoffImpl(this);
  }

  /**
   * Returns a copy of this {@link FluentBackoff} that instead uses the specified exponent to
   * control the exponential growth of delay.
   *
   * <p>Does not modify this object.
   *
   * @see FluentBackoff
   */
  public FluentBackoff withExponent(double exponent) {
    checkArgument(exponent > 0, "exponent %s must be greater than 0", exponent);
    return new FluentBackoff(
        exponent, initialBackoff, maxBackoff, maxCumulativeBackoff, maxRetries);
  }

  /**
   * Returns a copy of this {@link FluentBackoff} that instead uses the specified initial backoff
   * duration.
   *
   * <p>Does not modify this object.
   *
   * @see FluentBackoff
   */
  public FluentBackoff withInitialBackoff(Duration initialBackoff) {
    checkArgument(
        initialBackoff.isLongerThan(Duration.ZERO),
        "initialBackoff %s must be at least 1 millisecond",
        initialBackoff);
    return new FluentBackoff(
        exponent, initialBackoff, maxBackoff, maxCumulativeBackoff, maxRetries);
  }

  /**
   * Returns a copy of this {@link FluentBackoff} that limits the maximum backoff of an individual
   * attempt to the specified duration.
   *
   * <p>Does not modify this object.
   *
   * @see FluentBackoff
   */
  public FluentBackoff withMaxBackoff(Duration maxBackoff) {
    checkArgument(
        maxBackoff.getMillis() > 0, "maxBackoff %s must be at least 1 millisecond", maxBackoff);
    return new FluentBackoff(
        exponent, initialBackoff, maxBackoff, maxCumulativeBackoff, maxRetries);
  }

  /**
   * Returns a copy of this {@link FluentBackoff} that limits the total time spent in backoff
   * returned across all calls to {@link BackOff#nextBackOffMillis()}.
   *
   * <p>Does not modify this object.
   *
   * @see FluentBackoff
   */
  public FluentBackoff withMaxCumulativeBackoff(Duration maxCumulativeBackoff) {
    checkArgument(
        maxCumulativeBackoff.isLongerThan(Duration.ZERO),
        "maxCumulativeBackoff %s must be at least 1 millisecond",
        maxCumulativeBackoff);
    return new FluentBackoff(
        exponent, initialBackoff, maxBackoff, maxCumulativeBackoff, maxRetries);
  }

  /**
   * Returns a copy of this {@link FluentBackoff} that limits the total number of retries, aka the
   * total number of calls to {@link BackOff#nextBackOffMillis()} before returning {@link
   * BackOff#STOP}.
   *
   * <p>Does not modify this object.
   *
   * @see FluentBackoff
   */
  public FluentBackoff withMaxRetries(int maxRetries) {
    checkArgument(maxRetries >= 0, "maxRetries %s cannot be negative", maxRetries);
    return new FluentBackoff(
        exponent, initialBackoff, maxBackoff, maxCumulativeBackoff, maxRetries);
  }

  @Override
  public String toString() {
    return MoreObjects.toStringHelper(FluentBackoff.class)
        .add("exponent", exponent)
        .add("initialBackoff", initialBackoff)
        .add("maxBackoff", maxBackoff)
        .add("maxRetries", maxRetries)
        .add("maxCumulativeBackoff", maxCumulativeBackoff)
        .toString();
  }

  private static class BackoffImpl implements BackOff {

    // Customization of this backoff.
    private final FluentBackoff backoffConfig;
    // Current state
    private Duration currentCumulativeBackoff;
    private int currentRetry;

    @Override
    public void reset() {
      currentRetry = 0;
      currentCumulativeBackoff = Duration.ZERO;
    }

    @Override
    public long nextBackOffMillis() {
      // Maximum number of retries reached.
      if (currentRetry >= backoffConfig.maxRetries) {
        return BackOff.STOP;
      }
      // Maximum cumulative backoff reached.
      if (currentCumulativeBackoff.compareTo(backoffConfig.maxCumulativeBackoff) >= 0) {
        return BackOff.STOP;
      }

      double currentIntervalMillis =
          Math.min(
              backoffConfig.initialBackoff.getMillis()
                  * Math.pow(backoffConfig.exponent, currentRetry),
              backoffConfig.maxBackoff.getMillis());
      double randomOffset =
          (Math.random() * 2 - 1) * DEFAULT_RANDOMIZATION_FACTOR * currentIntervalMillis;
      long nextBackoffMillis = Math.round(currentIntervalMillis + randomOffset);
      // Cap to limit on cumulative backoff
      Duration remainingCumulative =
          backoffConfig.maxCumulativeBackoff.minus(currentCumulativeBackoff);
      nextBackoffMillis = Math.min(nextBackoffMillis, remainingCumulative.getMillis());

      // Update state and return backoff.
      currentCumulativeBackoff = currentCumulativeBackoff.plus(nextBackoffMillis);
      currentRetry += 1;
      return nextBackoffMillis;
    }

    private BackoffImpl(FluentBackoff backoffConfig) {
      this.backoffConfig = backoffConfig;
      this.reset();
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(BackoffImpl.class)
          .add("backoffConfig", backoffConfig)
          .add("currentRetry", currentRetry)
          .add("currentCumulativeBackoff", currentCumulativeBackoff)
          .toString();
    }
  }

  private FluentBackoff(
      double exponent,
      Duration initialBackoff,
      Duration maxBackoff,
      Duration maxCumulativeBackoff,
      int maxRetries) {
    this.exponent = exponent;
    this.initialBackoff = initialBackoff;
    this.maxBackoff = maxBackoff;
    this.maxRetries = maxRetries;
    this.maxCumulativeBackoff = maxCumulativeBackoff;
  }
}
