// Copyright (C) 2019 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.google.gerrit.server.notedb;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.CHANGE_MODIFICATION;

import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.MultimapBuilder;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.git.RefUpdateUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.FanOutExecutor;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.update.context.RefUpdateContext;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.transport.PushCertificate;

/**
 * Performs an update on {@code All-Users} asynchronously if required. No-op in case no updates were
 * scheduled for asynchronous execution.
 */
public class AllUsersAsyncUpdate {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final ExecutorService executor;
  private final AllUsersName allUsersName;
  private final GitRepositoryManager repoManager;
  private final GitReferenceUpdated gitReferenceUpdated;
  private final ListMultimap<String, ChangeDraftNotesUpdate> draftUpdates;

  private PersonIdent serverIdent;

  @Inject
  AllUsersAsyncUpdate(
      @FanOutExecutor ExecutorService executor,
      AllUsersName allUsersName,
      GitRepositoryManager repoManager,
      GitReferenceUpdated gitReferenceUpdated) {
    this.executor = executor;
    this.allUsersName = allUsersName;
    this.repoManager = repoManager;
    this.gitReferenceUpdated = gitReferenceUpdated;
    this.draftUpdates = MultimapBuilder.hashKeys().arrayListValues().build();
  }

  void setDraftUpdates(ListMultimap<String, ChangeDraftNotesUpdate> draftUpdates) {
    checkState(isEmpty(), "attempted to set draft comment updates for async execution twice");
    boolean allPublishOnly =
        draftUpdates.values().stream().allMatch(ChangeDraftNotesUpdate::canRunAsync);
    checkState(allPublishOnly, "not all updates can be run asynchronously");
    // Add deep copies to avoid any threading issues.
    for (Map.Entry<String, ChangeDraftNotesUpdate> entry : draftUpdates.entries()) {
      this.draftUpdates.put(entry.getKey(), entry.getValue().copy());
    }
    if (draftUpdates.size() > 0) {
      // Save the PersonIdent for later so that we get consistent time stamps in the commit and ref
      // log.
      serverIdent = Iterables.get(draftUpdates.entries(), 0).getValue().serverIdent;
    }
  }

  /** Returns true if no operations should be performed on the repo. */
  boolean isEmpty() {
    return draftUpdates.isEmpty();
  }

  /** Executes repository update asynchronously. No-op in case no updates were scheduled. */
  void execute(
      PersonIdent refLogIdent,
      String refLogMessage,
      PushCertificate pushCert,
      CurrentUser currentUser) {
    if (isEmpty()) {
      return;
    }

    @SuppressWarnings("unused")
    Future<?> possiblyIgnoredError =
        executor.submit(
            () -> {
              try (RefUpdateContext ctx = RefUpdateContext.open(CHANGE_MODIFICATION)) {
                try (OpenRepo allUsersRepo = OpenRepo.open(repoManager, allUsersName)) {
                  allUsersRepo.addUpdatesNoLimits(draftUpdates);
                  allUsersRepo.flush();
                  BatchRefUpdate bru = allUsersRepo.repo.getRefDatabase().newBatchUpdate();
                  bru.setPushCertificate(pushCert);
                  if (refLogMessage != null) {
                    bru.setRefLogMessage(refLogMessage, false);
                  } else {
                    bru.setRefLogMessage(
                        firstNonNull(NoteDbUtil.guessRestApiHandler(), "Update NoteDb refs async"),
                        false);
                  }
                  bru.setRefLogIdent(refLogIdent != null ? refLogIdent : serverIdent);
                  bru.setAtomic(true);
                  allUsersRepo.cmds.addTo(bru);
                  bru.setAllowNonFastForwards(true);
                  RefUpdateUtil.executeChecked(bru, allUsersRepo.rw);
                  gitReferenceUpdated.fire(allUsersName, bru, getAccountState(currentUser));
                } catch (IOException e) {
                  logger.atSevere().withCause(e).log(
                      "Failed to delete draft comments asynchronously after publishing them");
                }
              }
            });
  }

  @Nullable
  private static AccountState getAccountState(CurrentUser user) {
    return user.isIdentifiedUser() ? user.asIdentifiedUser().state() : null;
  }
}
