// Copyright (C) 2021 The Android Open Source Project
//
// 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.googlesource.gerrit.plugins.pubsub;

import com.gerritforge.gerrit.eventbroker.EventMessage;
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutureCallback;
import com.google.api.core.ApiFutures;
import com.google.cloud.pubsub.v1.Publisher;
import com.google.common.flogger.FluentLogger;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.JdkFutureAdapters;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.gerrit.server.events.Event;
import com.google.gson.Gson;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.protobuf.ByteString;
import com.google.pubsub.v1.PubsubMessage;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

public class PubSubPublisher {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public interface Factory {
    public PubSubPublisher create(String topic);
  }

  private final Gson gson;
  private final PubSubPublisherMetrics publisherMetrics;
  private final String topic;
  private final Publisher publisher;
  private final PubSubConfiguration pubSubProperties;

  @Inject
  public PubSubPublisher(
      PubSubConfiguration pubSubProperties,
      PublisherProvider publisherProvider,
      Gson gson,
      PubSubPublisherMetrics publisherMetrics,
      @Assisted String topic)
      throws IOException {
    this.gson = gson;
    this.publisherMetrics = publisherMetrics;
    this.topic = topic;
    this.publisher = publisherProvider.get(topic);
    this.pubSubProperties = pubSubProperties;
  }

  public ListenableFuture<Boolean> publish(Event event) {
    return publish(gson.toJson(event));
  }

  public ListenableFuture<Boolean> publish(EventMessage event) {
    return publish(gson.toJson(event));
  }

  private ListenableFuture<Boolean> publish(String eventPayload) {
    ByteString data = ByteString.copyFromUtf8(eventPayload);
    PubsubMessage pubsubMessage = PubsubMessage.newBuilder().setData(data).build();
    return publishAsync(pubsubMessage);
  }

  private ListenableFuture<Boolean> publishAsync(PubsubMessage pubsubMessage) {
    ApiFuture<String> publish = publisher.publish(pubsubMessage);
    ApiFutures.addCallback(
        publish,
        new ApiFutureCallback<String>() {
          @Override
          public void onFailure(Throwable t) {
            logger.atSevere().withCause(t).log(
                "Exception when publishing message (id:%s) to topic '%s' [message: %s]",
                pubsubMessage.getMessageId(), topic, pubsubMessage.getData().toStringUtf8());
            publisherMetrics.incrementFailedToPublishMessage();
          }

          @Override
          public void onSuccess(String messageId) {
            logger.atFine().log(
                "Successfully published message (id:%s) to topic '%s' [message: %s]",
                messageId, topic, pubsubMessage.getData().toStringUtf8());

            publisherMetrics.incrementSucceedToPublishMessage();
          }
        },
        MoreExecutors.directExecutor());

    return Futures.transform(
        JdkFutureAdapters.listenInPoolThread(publish),
        Objects::nonNull,
        MoreExecutors.directExecutor());
  }

  public void close() throws InterruptedException {
    if (publisher != null) {
      publisher.shutdown();
      publisher.awaitTermination(1, TimeUnit.MINUTES);
    }
  }
}
