// 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.plugins.checks.db;

import com.google.common.base.Throwables;
import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.DuplicateKeyException;
import com.google.gerrit.git.RefUpdateUtil;
import com.google.gerrit.plugins.checks.Checker;
import com.google.gerrit.plugins.checks.CheckerCreation;
import com.google.gerrit.plugins.checks.CheckerUpdate;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.plugins.checks.CheckersUpdate;
import com.google.gerrit.plugins.checks.NoSuchCheckerException;
import com.google.gerrit.plugins.checks.api.CheckerStatus;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.update.RetryHelper;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import java.io.IOException;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;

/** Class to write checkers to NoteDb. */
class NoteDbCheckersUpdate implements CheckersUpdate {
  interface Factory {
    /**
     * Creates a {@code CheckersUpdate} which uses the identity of the specified user to mark
     * database modifications executed by it. For NoteDb, this identity is used as author and
     * committer for all related commits.
     *
     * <p><strong>Note</strong>: Please use this method with care and consider using the {@link
     * com.google.gerrit.server.UserInitiated} annotation on the provider of a {@code
     * CheckersUpdate} instead.
     *
     * @param currentUser the user to which modifications should be attributed
     */
    NoteDbCheckersUpdate create(IdentifiedUser currentUser);

    /**
     * Creates a {@code CheckersUpdate} which uses the server identity to mark database
     * modifications executed by it. For NoteDb, this identity is used as author and committer for
     * all related commits.
     *
     * <p><strong>Note</strong>: Please use this method with care and consider using the {@link
     * com.google.gerrit.server.ServerInitiated} annotation on the provider of a {@code
     * CheckersUpdate} instead.
     */
    NoteDbCheckersUpdate createWithServerIdent();
  }

  private final GitRepositoryManager repoManager;
  private final AllProjectsName allProjectsName;
  private final MetaDataUpdateFactory metaDataUpdateFactory;
  private final GitReferenceUpdated gitRefUpdated;
  private final RetryHelper retryHelper;
  private final Optional<IdentifiedUser> currentUser;

  @AssistedInject
  NoteDbCheckersUpdate(
      GitRepositoryManager repoManager,
      AllProjectsName allProjectsName,
      MetaDataUpdate.InternalFactory metaDataUpdateInternalFactory,
      GitReferenceUpdated gitRefUpdated,
      RetryHelper retryHelper,
      @GerritPersonIdent PersonIdent serverIdent) {
    this(
        repoManager,
        allProjectsName,
        metaDataUpdateInternalFactory,
        gitRefUpdated,
        retryHelper,
        serverIdent,
        Optional.empty());
  }

  @AssistedInject
  NoteDbCheckersUpdate(
      GitRepositoryManager repoManager,
      AllProjectsName allProjectsName,
      MetaDataUpdate.InternalFactory metaDataUpdateInternalFactory,
      GitReferenceUpdated gitRefUpdated,
      RetryHelper retryHelper,
      @GerritPersonIdent PersonIdent serverIdent,
      @Assisted IdentifiedUser currentUser) {
    this(
        repoManager,
        allProjectsName,
        metaDataUpdateInternalFactory,
        gitRefUpdated,
        retryHelper,
        serverIdent,
        Optional.of(currentUser));
  }

  private NoteDbCheckersUpdate(
      GitRepositoryManager repoManager,
      AllProjectsName allProjectsName,
      MetaDataUpdate.InternalFactory metaDataUpdateInternalFactory,
      GitReferenceUpdated gitRefUpdated,
      RetryHelper retryHelper,
      @GerritPersonIdent PersonIdent serverIdent,
      Optional<IdentifiedUser> currentUser) {
    this.repoManager = repoManager;
    this.allProjectsName = allProjectsName;
    this.gitRefUpdated = gitRefUpdated;
    this.retryHelper = retryHelper;
    this.currentUser = currentUser;

    metaDataUpdateFactory =
        getMetaDataUpdateFactory(metaDataUpdateInternalFactory, currentUser, serverIdent);
  }

  @Override
  public Checker createChecker(CheckerCreation checkerCreation, CheckerUpdate checkerUpdate)
      throws DuplicateKeyException, IOException, ConfigInvalidException {
    try {
      return retryHelper
          .pluginUpdate(
              "createChecker", () -> createCheckerInNoteDb(checkerCreation, checkerUpdate))
          .call();
    } catch (Exception e) {
      Throwables.throwIfUnchecked(e);
      Throwables.throwIfInstanceOf(e, DuplicateKeyException.class);
      Throwables.throwIfInstanceOf(e, IOException.class);
      Throwables.throwIfInstanceOf(e, ConfigInvalidException.class);
      throw new IOException(e);
    }
  }

  private Checker createCheckerInNoteDb(
      CheckerCreation checkerCreation, CheckerUpdate checkerUpdate)
      throws DuplicateKeyException, IOException, ConfigInvalidException {
    try (Repository allProjectsRepo = repoManager.openRepository(allProjectsName)) {
      CheckerConfig checkerConfig =
          CheckerConfig.createForNewChecker(allProjectsName, allProjectsRepo, checkerCreation);
      checkerConfig.setCheckerUpdate(checkerUpdate);

      CheckersByRepositoryNotes checkersByRepositoryNotes =
          CheckersByRepositoryNotes.load(allProjectsName, allProjectsRepo);
      if (!checkerUpdate.getStatus().isPresent()
          || checkerUpdate.getStatus().get() == CheckerStatus.ENABLED) {
        // Only inserts to the notes if the status is not set or set as "ENABLED". Does not insert
        // if the checker is DISABLED.
        checkersByRepositoryNotes.insert(
            checkerCreation.getCheckerUuid(), checkerCreation.getRepository());
      }

      commit(allProjectsRepo, checkerConfig, checkersByRepositoryNotes);

      return checkerConfig
          .getLoadedChecker()
          .orElseThrow(
              () -> new IllegalStateException("Created checker wasn't automatically loaded"));
    }
  }

  private void commit(
      Repository allProjectsRepo,
      CheckerConfig checkerConfig,
      CheckersByRepositoryNotes checkersByRepositoryNotes)
      throws IOException {
    BatchRefUpdate batchRefUpdate = allProjectsRepo.getRefDatabase().newBatchUpdate();
    try (MetaDataUpdate metaDataUpdate =
        metaDataUpdateFactory.create(allProjectsName, allProjectsRepo, batchRefUpdate)) {
      checkerConfig.commit(metaDataUpdate);
      checkersByRepositoryNotes.commit(metaDataUpdate);
    }
    RefUpdateUtil.executeChecked(batchRefUpdate, allProjectsRepo);

    gitRefUpdated.fire(
        allProjectsName, batchRefUpdate, currentUser.map(user -> user.state()).orElse(null));
  }

  private static MetaDataUpdateFactory getMetaDataUpdateFactory(
      MetaDataUpdate.InternalFactory metaDataUpdateInternalFactory,
      Optional<IdentifiedUser> currentUser,
      PersonIdent serverIdent) {
    return (projectName, repository, batchRefUpdate) -> {
      MetaDataUpdate metaDataUpdate =
          metaDataUpdateInternalFactory.create(projectName, repository, batchRefUpdate);
      metaDataUpdate.getCommitBuilder().setCommitter(serverIdent);
      PersonIdent authorIdent;
      if (currentUser.isPresent()) {
        metaDataUpdate.setAuthor(currentUser.get());
        authorIdent =
            currentUser.get().newCommitterIdent(serverIdent.getWhen(), serverIdent.getTimeZone());
      } else {
        authorIdent = serverIdent;
      }
      metaDataUpdate.getCommitBuilder().setAuthor(authorIdent);
      return metaDataUpdate;
    };
  }

  @FunctionalInterface
  private interface MetaDataUpdateFactory {
    MetaDataUpdate create(
        Project.NameKey projectName, Repository repository, BatchRefUpdate batchRefUpdate)
        throws IOException;
  }

  @Override
  public Checker updateChecker(CheckerUuid checkerUuid, CheckerUpdate checkerUpdate)
      throws NoSuchCheckerException, IOException, ConfigInvalidException {
    return updateCheckerWithRetry(checkerUuid, checkerUpdate);
  }

  private Checker updateCheckerWithRetry(CheckerUuid checkerUuid, CheckerUpdate checkerUpdate)
      throws NoSuchCheckerException, IOException, ConfigInvalidException {
    try {
      return retryHelper
          .pluginUpdate("updateChecker", () -> updateCheckerInNoteDb(checkerUuid, checkerUpdate))
          .call();
    } catch (Exception e) {
      Throwables.throwIfUnchecked(e);
      Throwables.throwIfInstanceOf(e, IOException.class);
      Throwables.throwIfInstanceOf(e, ConfigInvalidException.class);
      Throwables.throwIfInstanceOf(e, NoSuchCheckerException.class);
      throw new IOException(e);
    }
  }

  private Checker updateCheckerInNoteDb(CheckerUuid checkerUuid, CheckerUpdate checkerUpdate)
      throws IOException, ConfigInvalidException, NoSuchCheckerException {
    try (Repository allProjectsRepo = repoManager.openRepository(allProjectsName)) {
      CheckerConfig checkerConfig =
          CheckerConfig.loadForChecker(allProjectsName, allProjectsRepo, checkerUuid);
      checkerConfig.setCheckerUpdate(checkerUpdate);
      if (!checkerConfig.getLoadedChecker().isPresent()) {
        throw new NoSuchCheckerException(checkerUuid);
      }

      CheckersByRepositoryNotes checkersByRepositoryNotes =
          CheckersByRepositoryNotes.load(allProjectsName, allProjectsRepo);

      Checker checker = checkerConfig.getLoadedChecker().get();
      Project.NameKey oldRepositoryName = checker.getRepository();
      Project.NameKey newRepositoryName = checkerUpdate.getRepository().orElse(oldRepositoryName);

      CheckerStatus newStatus = checkerUpdate.getStatus().orElse(checker.getStatus());
      switch (newStatus) {
          // May produce some redundant notes updates, but CheckersByRepositoryNotes knows how to
          // short-circuit on no-ops, and the logic in this method is simple.
        case DISABLED:
          checkersByRepositoryNotes.remove(checkerUuid, oldRepositoryName);
          checkersByRepositoryNotes.remove(checkerUuid, newRepositoryName);
          break;
        case ENABLED:
          if (oldRepositoryName.equals(newRepositoryName)) {
            checkersByRepositoryNotes.insert(checkerUuid, newRepositoryName);
          } else {
            checkersByRepositoryNotes.update(checkerUuid, oldRepositoryName, newRepositoryName);
          }
          break;
        default:
          throw new IllegalStateException("invalid checker status: " + newStatus);
      }

      commit(allProjectsRepo, checkerConfig, checkersByRepositoryNotes);

      Checker updatedChecker =
          checkerConfig
              .getLoadedChecker()
              .orElseThrow(
                  () -> new IllegalStateException("Updated checker wasn't automatically loaded"));
      return updatedChecker;
    }
  }
}
