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

import static com.google.cloud.pubsublite.internal.ExtractStatus.toCanonical;

import com.google.api.gax.rpc.ApiException;
import com.google.auto.value.AutoValue;
import com.google.cloud.pubsublite.AdminClient;
import com.google.cloud.pubsublite.AdminClientSettings;
import com.google.cloud.pubsublite.TopicPath;
import com.google.cloud.pubsublite.internal.wire.*;
import com.google.cloud.pubsublite.internal.wire.PubsubContext.Framework;
import com.google.cloud.pubsublite.v1.PublisherServiceClient;
import com.google.cloud.pubsublite.v1.PublisherServiceSettings;
import org.apache.kafka.clients.producer.Producer;

@AutoValue
public abstract class ProducerSettings {
  private static final Framework FRAMEWORK = Framework.of("KAFKA_SHIM");

  // Required parameters.
  abstract TopicPath topicPath();

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

  @AutoValue.Builder
  public abstract static class Builder {
    // Required parameters.
    public abstract Builder setTopicPath(TopicPath path);

    public abstract ProducerSettings build();
  }

  public Producer<byte[], byte[]> instantiate() throws ApiException {
    PartitionCountWatchingPublisherSettings publisherSettings =
        PartitionCountWatchingPublisherSettings.newBuilder()
            .setTopic(topicPath())
            .setPublisherFactory(
                partition -> {
                  try {
                    return SinglePartitionPublisherBuilder.newBuilder()
                        .setServiceClient(
                            PublisherServiceClient.create(
                                ServiceClients.addDefaultSettings(
                                    topicPath().location().region(),
                                    ServiceClients.addDefaultMetadata(
                                        PubsubContext.of(FRAMEWORK),
                                        RoutingMetadata.of(topicPath(), partition),
                                        PublisherServiceSettings.newBuilder()))))
                        .setTopic(topicPath())
                        .setPartition(partition)
                        .build();
                  } catch (Throwable t) {
                    throw toCanonical(t).underlying;
                  }
                })
            .build();
    SharedBehavior shared =
        new SharedBehavior(
            AdminClient.create(
                AdminClientSettings.newBuilder()
                    .setRegion(topicPath().location().region())
                    .build()));
    return new PubsubLiteProducer(publisherSettings.instantiate(), shared, topicPath());
  }
}

@@ -1735,16 +1735,187 @@
 );%0A  %7D%0A%0A
+  private AdminClient newAdminClient() %7B%0A    return AdminClient.create(%0A        AdminClientSettings.newBuilder().setRegion(topicPath().location().region()).build());%0A  %7D%0A%0A
   public
@@ -2128,32 +2128,78 @@
 ic(topicPath())%0A
+            .setAdminClient(newAdminClient())%0A
             .set
@@ -3200,24 +3200,16 @@
 shared =
-%0A       
  new Sha
@@ -3224,182 +3224,23 @@
 ior(
-%0A            AdminClient.create(%0A                AdminClientSettings.newBuilder()%0A                    .setRegion(topicPath().location().region())%0A                    .build()
+newAdminClient(
 ));%0A

Add admin client in producer settings (#82)