/*
 * Copyright 2020 Google LLC
 *
 * Licensed 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 com.google.cloud.pubsublite;

import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.pubsublite.internal.ChannelCache;
import com.google.common.collect.ImmutableList;
import io.grpc.Channel;
import io.grpc.auth.MoreCallCredentials;
import io.grpc.stub.AbstractStub;
import java.io.IOException;
import java.util.function.Function;

public class Stubs {
  private static final ChannelCache channels = new ChannelCache();

  public static <StubT extends AbstractStub<StubT>> StubT defaultStub(
      String target, Function<Channel, StubT> stubFactory) throws IOException {
    return stubFactory
        .apply(channels.get(target))
        .withCallCredentials(
            MoreCallCredentials.from(
                GoogleCredentials.getApplicationDefault()
                    .createScoped(
                        ImmutableList.of("https://www.googleapis.com/auth/cloud-platform"))));
  }

  private Stubs() {}
}

@@ -628,16 +628,167 @@
 blite;%0A%0A
+import com.google.api.gax.core.GaxProperties;%0Aimport com.google.api.gax.grpc.GaxGrpcProperties;%0Aimport com.google.api.gax.rpc.ApiClientHeaderProvider;%0A
 import c
@@ -950,22 +950,297 @@
 o.grpc.C
-hannel
+allOptions;%0Aimport io.grpc.Channel;%0Aimport io.grpc.ClientCall;%0Aimport io.grpc.ClientInterceptor;%0Aimport io.grpc.ClientInterceptors;%0Aimport io.grpc.ForwardingClientCall.SimpleForwardingClientCall;%0Aimport io.grpc.Metadata;%0Aimport io.grpc.Metadata.Key;%0Aimport io.grpc.MethodDescriptor
 ;%0Aimport
@@ -1336,16 +1336,117 @@
 eption;%0A
+import java.util.ArrayList;%0Aimport java.util.List;%0Aimport java.util.Map;%0Aimport java.util.Map.Entry;%0A
 import j
@@ -1756,27 +1756,82 @@
 ply(
-channels.get(target
+ClientInterceptors.intercept(channels.get(target), getClientInterceptors()
 ))%0A 
@@ -2090,16 +2090,1438 @@
 );%0A  %7D%0A%0A
+  private static List%3CClientInterceptor%3E getClientInterceptors() %7B%0A    List%3CClientInterceptor%3E clientInterceptors = new ArrayList%3C%3E();%0A    Map%3CString, String%3E apiClientHeaders =%0A        ApiClientHeaderProvider.newBuilder()%0A            .setClientLibToken(%22gccl%22, GaxProperties.getLibraryVersion(Stubs.class))%0A            .setTransportToken(%0A                GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion())%0A            .build()%0A            .getHeaders();%0A    clientInterceptors.add(%0A        new ClientInterceptor() %7B%0A          @Override%0A          public %3CReqT, RespT%3E ClientCall%3CReqT, RespT%3E interceptCall(%0A              MethodDescriptor%3CReqT, RespT%3E method, CallOptions callOptions, Channel next) %7B%0A            ClientCall%3CReqT, RespT%3E call = next.newCall(method, callOptions);%0A            return new SimpleForwardingClientCall%3CReqT, RespT%3E(call) %7B%0A              @Override%0A              public void start(ClientCall.Listener%3CRespT%3E responseListener, Metadata headers) %7B%0A                for (Entry%3CString, String%3E apiClientHeader : apiClientHeaders.entrySet()) %7B%0A                  headers.put(%0A                      Key.of(apiClientHeader.getKey(), Metadata.ASCII_STRING_MARSHALLER),%0A                      apiClientHeader.getValue());%0A                %7D%0A                super.start(responseListener, headers);%0A              %7D%0A            %7D;%0A          %7D%0A        %7D);%0A    return clientInterceptors;%0A  %7D%0A%0A
   privat

add api client headers to outbound requests (#182)