/*
 * 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.io.synthetic;

import static org.apache.beam.sdk.io.synthetic.delay.SyntheticDelay.delay;
import static org.apache.beam.vendor.guava.v20_0.com.google.common.base.Preconditions.checkArgument;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.apache.beam.sdk.io.synthetic.delay.SyntheticDelay;
import org.apache.beam.sdk.metrics.Counter;
import org.apache.beam.sdk.metrics.Metrics;
import org.apache.beam.sdk.transforms.DoFn;
import org.apache.beam.sdk.values.KV;
import org.apache.beam.vendor.guava.v20_0.com.google.common.cache.CacheBuilder;
import org.apache.beam.vendor.guava.v20_0.com.google.common.cache.CacheLoader;
import org.apache.beam.vendor.guava.v20_0.com.google.common.cache.LoadingCache;
import org.apache.beam.vendor.guava.v20_0.com.google.common.util.concurrent.RateLimiter;
import org.joda.time.Duration;

/**
 * This {@link SyntheticStep} class provides a parameterizable {@code DoFn} that consumes {@code
 * KV<byte[], byte[]>} and emits {@code KV<byte[], byte[]>}. Each emitted record will be slowed down
 * by a certain sleep time generated based on the specified sleep time distribution in {@link
 * SyntheticStep.Options}.
 *
 * <p>See {@link SyntheticStep.Options} for how to construct an instance. To construct a {@code
 * SyntheticStep} from SyntheticStep options, use:
 *
 * <pre>{@code
 * SyntheticStep.Options options = ...;
 *
 * // Construct the synthetic step with options.
 * SyntheticStep step = new SyntheticStep(options);
 * }</pre>
 */
public class SyntheticStep extends DoFn<KV<byte[], byte[]>, KV<byte[], byte[]>> {

  private final Options options;

  // used when maxWorkerThroughput is set
  private final KV<Long, Long> idAndThroughput;

  private final Counter throttlingCounter =
      Metrics.counter("dataflow-throttling-metrics", "throttling-msecs");

  /**
   * Static cache to store one worker level rate limiter for a step. Value in KV is the desired
   * rate.
   */
  private static LoadingCache<KV<Long, Long>, RateLimiter> rateLimiterCache =
      CacheBuilder.newBuilder()
          .build(
              new CacheLoader<KV<Long, Long>, RateLimiter>() {
                @Override
                public RateLimiter load(KV<Long, Long> pair) {
                  return RateLimiter.create(pair.getValue().doubleValue());
                }
              });

  public SyntheticStep(Options options) {
    options.validate();
    this.options = options;
    Random rand = new Random();
    // use a random id so that a pipeline could have multiple SyntheticSteps
    this.idAndThroughput = KV.of(rand.nextLong(), options.maxWorkerThroughput);
  }

  @ProcessElement
  public void processElement(ProcessContext c) throws Exception {
    byte[] key = c.element().getKey();
    byte[] val = c.element().getValue();

    int decimalPart = (int) options.outputRecordsPerInputRecord;
    double fractionalPart = options.outputRecordsPerInputRecord - decimalPart;

    // Use the hashcode of val as seed to make the test deterministic.
    long hashCodeOfVal = options.hashFunction().hashBytes(val).asLong();

    Random random = new Random(hashCodeOfVal);

    int i;
    for (i = 0; i < decimalPart; i++) {
      c.output(outputElement(key, val, hashCodeOfVal, i, random));
    }
    if (random.nextDouble() < fractionalPart) {
      c.output(outputElement(key, val, hashCodeOfVal, i, random));
    }
  }

  private KV<byte[], byte[]> outputElement(
      byte[] inputKey, byte[] inputValue, long inputValueHashcode, int index, Random random) {

    long seed = options.hashFunction().hashLong(inputValueHashcode + index).asLong();
    Duration delay = Duration.millis(options.nextDelay(seed));
    long millisecondsSpentSleeping = 0;

    while (delay.getMillis() > 0) {
      millisecondsSpentSleeping +=
          delay(delay, options.cpuUtilizationInMixedDelay, options.delayType, random);

      if (isWithinThroughputLimit()) {
        break;
      } else {
        // try an extra delay of 1 millisecond
        delay = Duration.millis(1);
      }
    }

    reportThrottlingTimeMetrics(millisecondsSpentSleeping);

    if (options.preservesInputKeyDistribution) {
      // Generate the new byte array value whose hashcode will be
      // used as seed to initialize a Random object in next stages.
      byte[] newValue = new byte[inputValue.length];
      random.nextBytes(newValue);
      return KV.of(inputKey, newValue);
    } else {
      return options.genKvPair(seed);
    }
  }

  private void reportThrottlingTimeMetrics(long milliseconds) {
    if (options.reportThrottlingMicros && milliseconds > 0) {
      throttlingCounter.inc(TimeUnit.MILLISECONDS.toMicros(milliseconds));
    }
  }

  private boolean isWithinThroughputLimit() {
    return options.maxWorkerThroughput < 0
        || rateLimiterCache.getUnchecked(idAndThroughput).tryAcquire();
  }

  @StartBundle
  public void startBundle() throws Exception {
    if (options.perBundleDelay > 0) {
      SyntheticDelay.delay(
          Duration.millis(options.perBundleDelay),
          options.cpuUtilizationInMixedDelay,
          options.perBundleDelayType,
          new Random());
    }
  }

  /**
   * Synthetic step options. These options are all JSON, see documentations of individual fields for
   * details. {@code Options} uses jackson annotations which PipelineOptionsFactory can use to parse
   * and construct an instance.
   */
  public static class Options extends SyntheticOptions {
    /**
     * Amplification/filtering ratio: the number of output records should be emitted on average for
     * each input record.
     */
    @JsonProperty public double outputRecordsPerInputRecord;

    /**
     * If false, the DoFn generates a different distribution of KV pairs according to the parameters
     * in {@link SyntheticOptions}, and input records are merely used as a “clock”; If true, the
     * shape of the input distribution is preserved, and the DoFn only does sleeping and
     * amplification/filtering.
     */
    @JsonProperty public boolean preservesInputKeyDistribution;

    /**
     * An upper limit on throughput across the worker for this step. In a streaming job, it is not
     * easy to tightly control parallelism of a DoFn. It depends on various factors. As a result, it
     * is much harder to control throughput preconfigured cpu or sleep delay. When max throughput is
     * set, SyntheticStep delays beyond the configured delay (either cpu or sleep) in order to keep
     * the overall throughput below the limit.
     */
    @JsonProperty public long maxWorkerThroughput = -1;

    /**
     * Number of milliseconds to delay for in each bundle. Cannot be enabled simultaneously with
     * {@code maxWorkerThroughput >= 0}.
     */
    @JsonProperty public long perBundleDelay = 0;

    /** Type of per bundle delay to use ("SLEEP", "CPU", "MIXED"). */
    @JsonProperty public DelayType perBundleDelayType = DelayType.SLEEP;

    /**
     * If true, reports time spent sleeping as 'cumulativeThrottlingMicros' metric. This enables
     * Dataflow to detect throttled stages, which would influence scaling decisions.
     */
    @JsonProperty public boolean reportThrottlingMicros;

    @Override
    public void validate() {
      super.validate();
      checkArgument(
          outputRecordsPerInputRecord >= 0,
          "outputRecordsPerInputRecord should be a non-negative number, but found %s.",
          outputRecordsPerInputRecord);
      checkArgument(
          perBundleDelay >= 0,
          "perBundleDelay should be a non-negative number, but found %s.",
          perBundleDelay);
      if (maxWorkerThroughput >= 0) {
        checkArgument(
            perBundleDelay == 0,
            "maxWorkerThroughput and perBundleDelay cannot be enabled simultaneously.");
      }
    }
  }
}
