// 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 static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.gerrit.exceptions.DuplicateKeyException;
import com.google.gerrit.plugins.checks.Checker;
import com.google.gerrit.plugins.checks.CheckerCreation;
import com.google.gerrit.plugins.checks.CheckerRef;
import com.google.gerrit.plugins.checks.CheckerUpdate;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.plugins.checks.Checkers;
import com.google.gerrit.plugins.checks.CheckersUpdate;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.NameKey;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.git.meta.VersionedMetaData;
import com.google.gerrit.server.util.time.TimeUtil;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;

/**
 * A representation of a checker in NoteDb.
 *
 * <p>Checkers in NoteDb can be created by following the descriptions of {@link
 * #createForNewChecker(Project.NameKey, Repository, CheckerCreation)}. For reading checkers from
 * NoteDb or updating them, refer to {@link #loadForChecker(Project.NameKey, Repository,
 * CheckerUuid)}.
 *
 * <p><strong>Note:</strong> Any modification (checker creation or update) only becomes permanent
 * (and hence written to NoteDb) if {@link #commit(MetaDataUpdate)} is called.
 *
 * <p><strong>Warning:</strong> This class is a low-level API for checkers in NoteDb. Most code
 * which deals with checkers should use {@link Checkers} or {@link CheckersUpdate} instead.
 *
 * <h2>Internal details</h2>
 *
 * <p>Each checker is represented by a commit on a branch as defined by {@link
 * CheckerUuid#toRefName()}. Previous versions of the checker exist as older commits on the same
 * branch and can be reached by following along the parent references. New commits for updates are
 * only created if a real modification occurs.
 *
 * <p>Within each commit, the properties of a checker are stored in <em>checker.config</em> file
 * (further specified by {@link CheckerConfigEntry}). The <em>checker.config</em> file is formatted
 * as a JGit {@link Config} file.
 */
@VisibleForTesting
public class CheckerConfig extends VersionedMetaData {
  @VisibleForTesting public static final String CHECKER_CONFIG_FILE = "checker.config";

  /**
   * Creates a {@code CheckerConfig} for a new checker from the {@code CheckerCreation} blueprint.
   * Further, optional properties can be specified by setting an {@code CheckerUpdate} via {@link
   * #setCheckerUpdate(CheckerUpdate)} on the returned {@code CheckerConfig}.
   *
   * <p><strong>Note:</strong> The returned {@code CheckerConfig} has to be committed via {@link
   * #commit(MetaDataUpdate)} in order to create the checker for real.
   *
   * @param projectName the name of the project which holds the NoteDb commits for checkers
   * @param repository the repository which holds the NoteDb commits for checkers
   * @param checkerCreation a {@code CheckerCreation} specifying all properties which are required
   *     for a new checker
   * @return a {@code CheckerConfig} for a checker creation
   * @throws IOException if the repository can't be accessed for some reason
   * @throws ConfigInvalidException if a checker with the same UUID already exists but can't be read
   *     due to an invalid format
   * @throws DuplicateKeyException if a checker with the same UUID already exists
   */
  public static CheckerConfig createForNewChecker(
      Project.NameKey projectName, Repository repository, CheckerCreation checkerCreation)
      throws IOException, ConfigInvalidException, DuplicateKeyException {
    CheckerConfig checkerConfig =
        loadForChecker(projectName, repository, checkerCreation.getCheckerUuid());
    checkerConfig.setCheckerCreation(checkerCreation);
    return checkerConfig;
  }

  /**
   * Creates a {@code CheckerConfig} for an existing checker.
   *
   * <p>The checker is automatically loaded within this method and can be accessed via {@link
   * #getLoadedChecker()}.
   *
   * <p>It's safe to call this method for non-existing checkers. In that case, {@link
   * #getLoadedChecker()} won't return any checker. Thus, the existence of a checker can be easily
   * tested.
   *
   * <p>The checker represented by the returned {@code CheckerConfig} can be updated by setting an
   * {@code CheckerUpdate} via {@link #setCheckerUpdate(CheckerUpdate)} and committing the {@code
   * CheckerConfig} via {@link #commit(MetaDataUpdate)}.
   *
   * @param projectName the name of the project which holds the NoteDb commits for checkers
   * @param repository the repository which holds the NoteDb commits for checkers
   * @param checkerUuid the UUID of the checker
   * @return a {@code CheckerConfig} for the checker with the specified UUID
   * @throws IOException if the repository can't be accessed for some reason
   * @throws ConfigInvalidException if the checker exists but can't be read due to an invalid format
   */
  public static CheckerConfig loadForChecker(
      Project.NameKey projectName, Repository repository, CheckerUuid checkerUuid)
      throws IOException, ConfigInvalidException {
    CheckerConfig checkerConfig = new CheckerConfig(checkerUuid);
    checkerConfig.load(projectName, repository);
    return checkerConfig;
  }

  /**
   * Creates a {@code CheckerConfig} for a known checker ref.
   *
   * <p>The checker is automatically loaded within this method and can be accessed via {@link
   * #getLoadedChecker()}.
   *
   * <p>It's safe to call this method for non-existing checkers. In that case, {@link
   * #getLoadedChecker()} won't return any checker. Thus, the existence of a checker can be easily
   * tested.
   *
   * <p>The checker represented by the returned {@code CheckerConfig} can be updated by setting an
   * {@code CheckerUpdate} via {@link #setCheckerUpdate(CheckerUpdate)} and committing the {@code
   * CheckerConfig} via {@link #commit(MetaDataUpdate)}.
   *
   * @param projectName the name of the project which holds the NoteDb commits for checkers
   * @param repository the repository which holds the NoteDb commits for checkers
   * @param ref the checker ref; the refname must pass {@link CheckerRef#isRefsCheckers(String)}.
   * @return a {@code CheckerConfig} for the checker with the specified UUID
   * @throws IOException if the repository can't be accessed for some reason
   * @throws ConfigInvalidException if the checker exists but can't be read due to an invalid format
   */
  public static CheckerConfig loadForChecker(NameKey projectName, Repository repository, Ref ref)
      throws IOException, ConfigInvalidException {
    CheckerConfig checkerConfig = new CheckerConfig(ref.getName());
    checkerConfig.load(projectName, repository);
    return checkerConfig;
  }

  private final String ref;

  private Optional<CheckerUuid> checkerUuid;
  private Optional<Checker> loadedChecker = Optional.empty();
  private Optional<CheckerCreation> checkerCreation = Optional.empty();
  private Optional<CheckerUpdate> checkerUpdate = Optional.empty();
  private Optional<Checker.Builder> updatedCheckerBuilder = Optional.empty();
  private Optional<Config> loadedConfig = Optional.empty();
  private boolean isLoaded = false;

  private CheckerConfig(String ref) {
    checkArgument(CheckerRef.isRefsCheckers(ref), "expected checker ref: %s", ref);
    this.ref = ref;
    this.checkerUuid = Optional.empty();
  }

  private CheckerConfig(CheckerUuid checkerUuid) {
    this(checkerUuid.toRefName());
    this.checkerUuid = Optional.of(checkerUuid);
  }

  /**
   * Returns the checker loaded from NoteDb.
   *
   * <p>If not any NoteDb commits exist for the checker represented by this {@code CheckerConfig},
   * no checker is returned.
   *
   * <p>After {@link #commit(MetaDataUpdate)} was called on this {@code CheckerConfig}, this method
   * returns a checker which is in line with the latest NoteDb commit for this checker. So, after
   * creating a {@code CheckerConfig} for a new checker and committing it, this method can be used
   * to retrieve a representation of the created checker. The same holds for the representation of
   * an updated checker.
   *
   * @return the loaded checker, or an empty {@code Optional} if the checker doesn't exist
   */
  public Optional<Checker> getLoadedChecker() {
    checkLoaded();

    if (updatedCheckerBuilder.isPresent()) {
      // There have been updates to the checker that have not been applied to the loaded checker
      // yet, apply them now. This has to be done here because in the onSave(CommitBuilder) method
      // where the checker updates are committed we do not know the new SHA1 for the ref state
      // yet.
      loadedChecker = Optional.of(updatedCheckerBuilder.get().setRefState(revision).build());
      updatedCheckerBuilder = Optional.empty();
    }

    return loadedChecker;
  }

  /**
   * Specifies how the current checker should be updated.
   *
   * <p>If the checker is newly created, the {@code CheckerUpdate} can be used to specify optional
   * properties.
   *
   * <p><strong>Note:</strong> This method doesn't perform the update. It only contains the
   * instructions for the update. To apply the update for real and write the result back to NoteDb,
   * call {@link #commit(MetaDataUpdate)} on this {@code CheckerConfig}.
   *
   * @param checkerUpdate an {@code CheckerUpdate} outlining the modifications which should be
   *     applied
   */
  public void setCheckerUpdate(CheckerUpdate checkerUpdate) {
    this.checkerUpdate = Optional.of(checkerUpdate);
  }

  private void setCheckerCreation(CheckerCreation checkerCreation) throws DuplicateKeyException {
    checkLoaded();
    if (loadedChecker.isPresent()) {
      throw new DuplicateKeyException(
          String.format("Checker %s already exists", loadedChecker.get().getUuid()));
    }

    this.checkerCreation = Optional.of(checkerCreation);
  }

  @Override
  protected String getRefName() {
    return ref;
  }

  @VisibleForTesting
  public Optional<Config> getConfigForTesting() {
    return loadedConfig;
  }

  @Override
  protected void onLoad() throws IOException, ConfigInvalidException {
    if (revision != null) {
      rw.reset();
      rw.markStart(revision);
      rw.sort(RevSort.REVERSE);
      RevCommit earliestCommit = rw.next();
      Timestamp created = new Timestamp(earliestCommit.getCommitTime() * 1000L);
      Timestamp updated = new Timestamp(rw.parseCommit(revision).getCommitTime() * 1000L);

      Config checkerConfig = readConfig(CHECKER_CONFIG_FILE);
      Checker checker = createFrom(checkerConfig, created, updated, revision.toObjectId());
      loadedChecker = Optional.of(checker);
      loadedConfig = Optional.of(checkerConfig);
      checkerUuid = Optional.of(checker.getUuid());
    }

    isLoaded = true;
  }

  @Override
  protected boolean onSave(CommitBuilder commit) throws IOException, ConfigInvalidException {
    checkLoaded();
    if (!checkerCreation.isPresent() && !checkerUpdate.isPresent()) {
      // Checker was neither created nor changed. -> A new commit isn't necessary.
      return false;
    }

    ensureThatMandatoryPropertiesAreSet();

    // Commit timestamps are internally truncated to seconds. To return the correct 'created' time
    // for new checkers, we explicitly need to truncate the timestamp here.
    Timestamp commitTimestamp =
        TimeUtil.truncateToSecond(new Timestamp(commit.getCommitter().getWhen().getTime()));
    commit.setAuthor(new PersonIdent(commit.getAuthor(), commitTimestamp));
    commit.setCommitter(new PersonIdent(commit.getCommitter(), commitTimestamp));

    Config oldConfig = copyOrElseNew(loadedConfig);
    Config newConfig = copyOrElseNew(loadedConfig);

    Checker.Builder checker = updateChecker(newConfig, commitTimestamp);

    if (oldConfig.toText().equals(newConfig.toText())) {
      // Don't create a new commit if nothing was changed.
      return false;
    }

    updatedCheckerBuilder = Optional.of(checker);
    checkerUuid = Optional.of(checker.getUuid());
    loadedConfig = Optional.of(newConfig);

    String commitMessage = createCommitMessage(loadedChecker);
    commit.setMessage(commitMessage);

    checkerCreation = Optional.empty();
    checkerUpdate = Optional.empty();

    return true;
  }

  private String describeForError() {
    return checkerUuid.map(CheckerUuid::get).orElse(ref);
  }

  private void ensureThatMandatoryPropertiesAreSet() throws ConfigInvalidException {
    if (getNewRepository().equals(Optional.of(""))) {
      throw new ConfigInvalidException(
          String.format("Repository of the checker %s must be defined", describeForError()));
    }
  }

  private void checkLoaded() {
    checkState(isLoaded, "Checker %s not loaded yet", describeForError());
  }

  private Optional<String> getNewRepository() {
    if (checkerUpdate.isPresent()) {
      return checkerUpdate
          .get()
          .getRepository()
          .map(Project.NameKey::get)
          .map(Strings::nullToEmpty)
          .map(String::trim);
    }
    if (checkerCreation.isPresent()) {
      return Optional.of(Strings.nullToEmpty(checkerCreation.get().getRepository().get()).trim());
    }
    return Optional.empty();
  }

  private Checker.Builder updateChecker(Config config, Timestamp commitTimestamp)
      throws IOException, ConfigInvalidException {
    updateCheckerProperties(config);
    Timestamp created = loadedChecker.map(Checker::getCreated).orElse(commitTimestamp);
    return createBuilderFrom(config, created, commitTimestamp);
  }

  private void updateCheckerProperties(Config config) throws IOException {
    checkerCreation.ifPresent(
        checkerCreation ->
            Arrays.stream(CheckerConfigEntry.values())
                .forEach(configEntry -> configEntry.initNewConfig(config, checkerCreation)));
    checkerUpdate.ifPresent(
        checkerUpdate ->
            Arrays.stream(CheckerConfigEntry.values())
                .forEach(configEntry -> configEntry.updateConfigValue(config, checkerUpdate)));
    saveConfig(CHECKER_CONFIG_FILE, config);
  }

  private Checker.Builder createBuilderFrom(Config config, Timestamp created, Timestamp updated)
      throws ConfigInvalidException {
    Checker.Builder checker = Checker.builder();

    // Populate UUID first so it can be used while reading other fields. The checkerUuid field may
    // or may not be present at this point; passing it in causes readFromConfig to double-check
    // equality.
    CheckerConfigEntry.UUID.readFromConfig(checkerUuid.orElse(null), checker, config);

    for (CheckerConfigEntry configEntry : CheckerConfigEntry.values()) {
      if (configEntry == CheckerConfigEntry.UUID) {
        continue;
      }
      configEntry.readFromConfig(checker.getUuid(), checker, config);
    }
    return checker.setCreated(created).setUpdated(updated);
  }

  private Checker createFrom(Config config, Timestamp created, Timestamp updated, ObjectId refState)
      throws ConfigInvalidException {
    return createBuilderFrom(config, created, updated).setRefState(refState).build();
  }

  private static String createCommitMessage(Optional<Checker> originalChecker) {
    return originalChecker.isPresent() ? "Update checker" : "Create checker";
  }

  private static Config copyOrElseNew(Optional<Config> config) throws ConfigInvalidException {
    return config.isPresent() ? copyConfig(config.get()) : new Config();
  }

  /**
   * Copies the provided config.
   *
   * <p><strong>Note:</strong> This method only works for configs that have no base config.
   * Unfortunately we cannot check that the provided config has no base config, so callers must take
   * care to use this method only for configs without base config.
   *
   * @param config the config that should be copied
   * @return the copy of the config
   */
  private static Config copyConfig(Config config) throws ConfigInvalidException {
    Config copiedConfig = new Config();
    copiedConfig.fromText(config.toText());
    return copiedConfig;
  }
}
