/*
 * Copyright 2016, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.google.api.gax.grpc;

import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * InstantiatingChannelProvider is an ExecutorProvider which constructs a new
 * ScheduledExecutorService every time getExecutor() is called. *
 */
public final class InstantiatingExecutorProvider implements ExecutorProvider {

  private final int executorThreadCount;

  private InstantiatingExecutorProvider(int executorThreadCount) {
    this.executorThreadCount = executorThreadCount;
  }

  @Override
  public ScheduledExecutorService getExecutor() {
    return MoreExecutors.getExitingScheduledExecutorService(
        new ScheduledThreadPoolExecutor(executorThreadCount));
  }

  @Override
  public boolean shouldAutoClose() {
    return true;
  }

  /**
   * The number of threads used by the executor created by this ExecutorProvider.
   */
  public int getExecutorThreadCount() {
    return executorThreadCount;
  }

  public Builder toBuilder() {
    return new Builder(this);
  }

  public static Builder newBuilder() {
    return new Builder();
  }

  public static final class Builder {
    // The number of threads to use with the default executor.
    private static final int DEFAULT_EXECUTOR_THREADS = 4;

    private int executorThreadCount = DEFAULT_EXECUTOR_THREADS;

    private Builder() {}

    /**
     * Sets the number of threads for the constructed executor to use.
     */
    public Builder setExecutorThreadCount(int executorThreadCount) {
      this.executorThreadCount = executorThreadCount;
      return this;
    }

    /**
     * The previously-set executor thread count.
     */
    public int getExecutorThreadCount() {
      return executorThreadCount;
    }

    private Builder(InstantiatingExecutorProvider provider) {
      this.executorThreadCount = provider.executorThreadCount;
    }

    public InstantiatingExecutorProvider build() {
      return new InstantiatingExecutorProvider(executorThreadCount);
    }
  }
}

@@ -1587,16 +1587,56 @@
 .grpc;%0A%0A
+import com.google.auto.value.AutoValue;%0A
 import c
@@ -1944,27 +1944,39 @@
 led.
- *
 %0A */%0A
-public final
+@AutoValue%0Apublic abstract
  cla
@@ -2042,50 +2042,68 @@
 r %7B%0A
-%0A  private final int executorThreadCount;%0A
+  // The number of threads to use with the default executor.
 %0A  p
@@ -2113,119 +2113,158 @@
 ate 
-In
 sta
-n
 ti
-atingExecutorProvider(int executorThreadCount) %7B%0A    this.executorThreadCount = executorThreadCount;%0A  
+c final int DEFAULT_EXECUTOR_THREADS = 4;%0A%0A  // Package-private constructor prevents others from subclassing.%0A  InstantiatingExecutorProvider() %7B
 %7D%0A%0A 
@@ -2425,17 +2425,20 @@
 xecutor(
-e
+getE
 xecutorT
@@ -2447,16 +2447,18 @@
 eadCount
+()
 ));%0A  %7D%0A
@@ -2624,32 +2624,41 @@
 %0A   */%0A  public 
+abstract 
 int getExecutorT
@@ -2673,46 +2673,9 @@
 nt()
- %7B%0A    return executorThreadCount;%0A  %7D
+;
 %0A%0A  
@@ -2710,32 +2710,72 @@
 %0A    return new 
+AutoValue_InstantiatingExecutorProvider.
 Builder(this);%0A 
@@ -2836,202 +2836,71 @@
 new 
-Builder();%0A  %7D%0A%0A  public static final class Builder %7B%0A    // The number of threads to use with the default executor.%0A    private static final int DEFAULT_EXECUTOR_THREADS = 4;%0A%0A    private int e
+AutoValue_InstantiatingExecutorProvider.Builder()%0A        .setE
 xecu
@@ -2913,19 +2913,17 @@
 eadCount
- = 
+(
 DEFAULT_
@@ -2942,123 +2942,77 @@
 EADS
+)
 ;
-%0A
 %0A  
-  private Builder() %7B%7D%0A%0A    /**%0A     * Sets the number of threads for the constructed executor to use.%0A     */
+%7D%0A%0A  @AutoValue.Builder%0A  public static abstract class Builder %7B
 %0A   
@@ -3011,32 +3011,41 @@
 er %7B%0A    public 
+abstract 
 Builder setExecu
@@ -3067,516 +3067,126 @@
 int 
-executorThreadCount) %7B%0A      this.executorThreadCount = executorThreadCount;%0A      return this;%0A    %7D%0A%0A    /**%0A     * The previously-set executor thread count.%0A     */%0A    public int getExecutorThreadCount() %7B%0A      return executorThreadCount;%0A    %7D%0A%0A    private Builder(InstantiatingExecutorProvider provider) %7B%0A      this.executorThreadCount = provider.executorThreadCount;%0A    %7D%0A%0A    public InstantiatingExecutorProvider build() %7B%0A      return new InstantiatingExecutorProvider(executorThreadCount);%0A    %7D
+value);%0A%0A    public abstract int getExecutorThreadCount();%0A%0A    public abstract InstantiatingExecutorProvider build();
 %0A  %7D

make InstantiatingExecutorProvider use AutoValue (#171)