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

import static com.google.cloud.pubsublite.internal.UncheckedApiPreconditions.checkArgument;

import com.google.api.core.ApiService.Listener;
import com.google.api.core.ApiService.State;
import com.google.api.gax.rpc.ApiException;
import com.google.cloud.pubsublite.MessageMetadata;
import com.google.cloud.pubsublite.internal.CloseableMonitor;
import com.google.cloud.pubsublite.internal.Publisher;
import com.google.errorprone.annotations.concurrent.GuardedBy;
import java.util.HashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.annotations.VisibleForTesting;

/** A map of working publishers by PublisherOptions. */
class PublisherCache {
  private final CloseableMonitor monitor = new CloseableMonitor();

  private final Executor listenerExecutor = Executors.newSingleThreadExecutor();

  @GuardedBy("monitor.monitor")
  private final HashMap<PublisherOptions, Publisher<MessageMetadata>> livePublishers =
      new HashMap<>();

  Publisher<MessageMetadata> get(PublisherOptions options) throws ApiException {
    checkArgument(options.usesCache());
    try (CloseableMonitor.Hold h = monitor.enter()) {
      Publisher<MessageMetadata> publisher = livePublishers.get(options);
      if (publisher != null) {
        return publisher;
      }
      publisher = Publishers.newPublisher(options);
      livePublishers.put(options, publisher);
      publisher.addListener(
          new Listener() {
            @Override
            public void failed(State s, Throwable t) {
              try (CloseableMonitor.Hold h = monitor.enter()) {
                livePublishers.remove(options);
              }
            }
          },
          listenerExecutor);
      publisher.startAsync().awaitRunning();
      return publisher;
    }
  }

  @VisibleForTesting
  void set(PublisherOptions options, Publisher<MessageMetadata> toCache) {
    try (CloseableMonitor.Hold h = monitor.enter()) {
      livePublishers.put(options, toCache);
    }
  }
}
