/*
 * 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.drill.exec.testing;

import java.util.List;

import org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint;

import com.google.common.collect.Lists;

import static org.apache.drill.exec.testing.ExecutionControls.EMPTY_CONTROLS;

public class Controls {

  /**
   * Returns a builder that can be used to add injections.
   *
   * @return a builder instance
   */
  public static Builder newBuilder() {
    return new Builder();
  }

  /**
   * Constructor. To disallow building controls without the builder.
   */
  private Controls() {
  }

  /**
   * A builder to create a controls string, a JSON that holds a list of injections that are to be injected in code for
   * testing purposes. This string is passed through the
   * {@link org.apache.drill.exec.ExecConstants#DRILLBIT_CONTROL_INJECTIONS} session option.
   * <p/>
   * The builder class can be reused; it is safe to call build() multiple times to build multiple controls strings in
   * series. Each new controls string contains all the injections added to the builder before it.
   */
  public static class Builder {

    private final List<String> injections = Lists.newArrayList();

    public Builder() {
    }

    /**
     * Adds an exception injection to the controls builder with the given parameters.
     *
     * @param siteClass      class where the exception should be thrown
     * @param desc           descriptor for the exception site in the site class
     * @param exceptionClass class of the exception to throw
     * @param nSkip          number of times to skip before firing
     * @param nFire          number of times to fire the exception
     * @return this builder
     */
    public Builder addException(final Class<?> siteClass, final String desc,
                                final Class<? extends Throwable> exceptionClass, final int nSkip,
                                final int nFire) {
      injections.add(ControlsInjectionUtil.createException(siteClass, desc, nSkip, nFire, exceptionClass));
      return this;
    }

    /**
     * Adds an exception injection to the controls builder with the given parameters. The injection is not skipped, and
     * the exception is thrown when execution reaches the site.
     *
     * @param siteClass      class where the exception should be thrown
     * @param desc           descriptor for the exception site in the site class
     * @param exceptionClass class of the exception to throw
     * @return this builder
     */
    public Builder addException(final Class<?> siteClass, final String desc,
                                final Class<? extends Throwable> exceptionClass) {
      return addException(siteClass, desc, exceptionClass, 0, 1);
    }

    /**
     * Adds an exception injection (for the specified drillbit) to the controls builder with the given parameters.
     *
     * @param siteClass      class where the exception should be thrown
     * @param desc           descriptor for the exception site in the site class
     * @param exceptionClass class of the exception to throw
     * @param endpoint       the endpoint of the drillbit on which to inject
     * @param nSkip          number of times to skip before firing
     * @param nFire          number of times to fire the exception
     * @return this builder
     */
    public Builder addExceptionOnBit(final Class<?> siteClass, final String desc,
                                     final Class<? extends Throwable> exceptionClass,
                                     final DrillbitEndpoint endpoint, final int nSkip,
                                     final int nFire) {
      injections.add(ControlsInjectionUtil.createExceptionOnBit(siteClass, desc, nSkip, nFire, exceptionClass,
        endpoint));
      return this;
    }

    /**
     * Adds an exception injection (for the specified drillbit) to the controls builder with the given parameters. The
     * injection is not skipped, and the exception is thrown when execution reaches the site on the specified drillbit.
     *
     * @param siteClass      class where the exception should be thrown
     * @param desc           descriptor for the exception site in the site class
     * @param exceptionClass class of the exception to throw
     * @param endpoint       endpoint of the drillbit on which to inject
     * @return this builder
     */
    public Builder addExceptionOnBit(final Class<?> siteClass, final String desc,
                                     final Class<? extends Throwable> exceptionClass,
                                     final DrillbitEndpoint endpoint) {
      return addExceptionOnBit(siteClass, desc, exceptionClass, endpoint, 0, 1);
    }

    /**
     * Adds a pause injection to the controls builder with the given parameters.
     *
     * @param siteClass class where the pause should happen
     * @param desc      descriptor for the pause site in the site class
     * @param nSkip     number of times to skip before firing
     * @return this builder
     */
    public Builder addPause(final Class<?> siteClass, final String desc, final int nSkip) {
      injections.add(ControlsInjectionUtil.createPause(siteClass, desc, nSkip));
      return this;
    }

    /**
     * Adds a time-bound pause injection to the controls builder with the given parameters.
     *
     * @param siteClass class where the pause should happen
     * @param desc      descriptor for the pause site in the site class
     * @param nSkip     number of times to skip before firing
     * @param msPause     duration of the pause in millisec
     * @return this builder
     */
    public Builder addTimedPause(final Class<?> siteClass, final String desc, final int nSkip, final long msPause) {
      injections.add(ControlsInjectionUtil.createTimedPause(siteClass, desc, nSkip, msPause));
      return this;
    }

    /**
     * Adds a pause injection to the controls builder with the given parameters. The pause is not skipped i.e. the pause
     * happens when execution reaches the site.
     *
     * @param siteClass class where the pause should happen
     * @param desc      descriptor for the pause site in the site class
     * @return this builder
     */
    public Builder addPause(final Class<?> siteClass, final String desc) {
      return addPause(siteClass, desc, 0);
    }

    /**
     * Adds a pause injection (for the specified drillbit) to the controls builder with the given parameters.
     *
     * @param siteClass class where the pause should happen
     * @param desc      descriptor for the pause site in the site class
     * @param nSkip     number of times to skip before firing
     * @return this builder
     */
    public Builder addPauseOnBit(final Class<?> siteClass, final String desc,
                                 final DrillbitEndpoint endpoint, final int nSkip) {
      injections.add(ControlsInjectionUtil.createPauseOnBit(siteClass, desc, nSkip, endpoint));
      return this;
    }

    /**
     * Adds a time-bound pause injection (for the specified drillbit) to the controls builder with the given parameters.
     *
     * @param siteClass class where the pause should happen
     * @param desc      descriptor for the pause site in the site class
     * @param nSkip     number of times to skip before firing
     * @param msPause     duration of the pause in millisec
     * @return this builder
     */
    public Builder addTimedPauseOnBit(final Class<?> siteClass, final String desc,
                                 final DrillbitEndpoint endpoint, final int nSkip, final long msPause) {
      injections.add(ControlsInjectionUtil.createTimedPauseOnBit(siteClass, desc, nSkip, endpoint, msPause));
      return this;
    }

    /**
     * Adds a pause injection (for the specified drillbit) to the controls builder with the given parameters. The pause
     * is not skipped i.e. the pause happens when execution reaches the site.
     *
     * @param siteClass class where the pause should happen
     * @param desc      descriptor for the pause site in the site class
     * @return this builder
     */
    public Builder addPauseOnBit(final Class<?> siteClass, final String desc,
                                 final DrillbitEndpoint endpoint) {
      return addPauseOnBit(siteClass, desc, endpoint, 0);
    }

    /**
     * Adds a count down latch to the controls builder with the given parameters.
     *
     * @param siteClass class where the latch should be injected
     * @param desc      descriptor for the latch in the site class
     * @return this builder
     */
    public Builder addLatch(final Class<?> siteClass, final String desc) {
      injections.add(ControlsInjectionUtil.createLatch(siteClass, desc));
      return this;
    }

    /**
     * Builds the controls string.
     *
     * @return a validated controls string with the added injections
     * @throws java.lang.AssertionError if controls cannot be validated using
     *                                  {@link org.apache.drill.exec.testing.ExecutionControls#controlsOptionMapper}
     */
    public String build() {
      if (injections.size() == 0) {
        return EMPTY_CONTROLS;
      }

      final StringBuilder builder = new StringBuilder("{ \"injections\" : [");
      for (final String injection : injections) {
        builder.append(injection)
          .append(",");
      }
      builder.setLength(builder.length() - 1); // remove the extra ","
      builder.append("]}");
      final String controls = builder.toString();
      ControlsInjectionUtil.validateControlsString(controls);
      return controls;
    }
  }
}
