// 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.checkState;
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Comparator.naturalOrder;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.flogger.FluentLogger;
import com.google.common.hash.Hashing;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Project;
import com.google.gerrit.plugins.checks.CheckerRef;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.git.meta.VersionedMetaData;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * {@link VersionedMetaData} subclass to read/update the repository to checkers map.
 *
 * <p>The map of repository to checkers is stored in the {@code refs/meta/checkers} notes branch in
 * the {@code All-Projects} repository. The note ID is a SHA1 that is computed from the repository
 * name. The node content is a plain list of checker UUIDs, one checker UUID per line.
 *
 * <p>This is a low-level API. Reading of the repository to checkers map should be done through
 * {@link
 * com.google.gerrit.plugins.checks.Checkers#checkersOf(com.google.gerrit.entities.Project.NameKey)}.
 * Updates to the repository to checkers map are done automatically when creating/updating checkers
 * through {@link com.google.gerrit.plugins.checks.CheckersUpdate}.
 *
 * <p>On load the note map from {@code refs/meta/checkers} is read, but the checker lists are not
 * parsed yet (see {@link #onLoad()}).
 *
 * <p>After loading the note map callers can access the checker list for a single repository. Only
 * now the requested checker list is parsed.
 *
 * <p>After loading the note map callers can stage various updates for the repository to checker map
 * (insert, update, remove).
 *
 * <p>On save the staged updates for the repository to checkers map are performed (see {@link
 * #onSave(CommitBuilder)}).
 */
@VisibleForTesting
public class CheckersByRepositoryNotes extends VersionedMetaData {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private static final int MAX_NOTE_SZ = 1 << 19;

  public static CheckersByRepositoryNotes load(
      AllProjectsName allProjectsName, Repository allProjectsRepo) throws IOException {
    return new CheckersByRepositoryNotes(allProjectsName, allProjectsRepo).load();
  }

  public static CheckersByRepositoryNotes load(
      AllProjectsName allProjectsName, Repository allProjectsRepo, @Nullable ObjectId rev)
      throws IOException, ConfigInvalidException {
    return new CheckersByRepositoryNotes(allProjectsName, allProjectsRepo).load(rev);
  }

  private final AllProjectsName allProjectsName;
  private final Repository repo;

  // the loaded note map
  private NoteMap noteMap;

  // Staged note map updates that should be executed on save.
  private List<NoteMapUpdate> noteMapUpdates = new ArrayList<>();

  private CheckersByRepositoryNotes(AllProjectsName allProjectsName, Repository allProjectsRepo) {
    this.allProjectsName = requireNonNull(allProjectsName, "allProjectsName");
    this.repo = requireNonNull(allProjectsRepo, "allProjectsRepo");
  }

  public Repository getRepository() {
    return repo;
  }

  @Override
  protected String getRefName() {
    return CheckerRef.REFS_META_CHECKERS;
  }

  /**
   * Loads the checkers by repository notes from the current tip of the {@code refs/meta/checkers}
   * branch.
   *
   * @return {@link CheckersByRepositoryNotes} instance for chaining
   */
  private CheckersByRepositoryNotes load() throws IOException {
    try {
      super.load(allProjectsName, repo);
    } catch (ConfigInvalidException e) {
      // load only throws ConfigInvalidException if it's propagating from onLoad.
      throw new IllegalStateException(e);
    }
    return this;
  }

  /**
   * Loads the checkers by repository notes from the specified revision of the {@code
   * refs/meta/checkers} branch.
   *
   * @param rev the revision from which the checkers by repository notes should be loaded, if {@code
   *     null} the checkers by repository notes are loaded from the current tip, if {@link
   *     ObjectId#zeroId()} it's assumed that the {@code refs/meta/checkers} branch doesn't exist
   *     and the loaded checkers by repository will be empty
   * @return {@link CheckersByRepositoryNotes} instance for chaining
   */
  CheckersByRepositoryNotes load(@Nullable ObjectId rev)
      throws IOException, ConfigInvalidException {
    if (rev == null) {
      return load();
    }
    if (ObjectId.zeroId().equals(rev)) {
      super.load(allProjectsName, repo, null);
      return this;
    }
    super.load(allProjectsName, repo, rev);
    return this;
  }

  /**
   * Parses and returns the set of checker UUIDs for the specified repository.
   *
   * <p>Invalid checker UUIDs are silently ignored.
   *
   * @param repositoryName the name of the repository for which the set of checker UUIDs should be
   *     parsed and returned
   * @return the set of checker UUIDs for the specified repository, empty set if no checkers apply
   *     for this repository
   * @throws IOException if reading the note with the checker UUID list fails
   */
  public ImmutableSortedSet<CheckerUuid> get(Project.NameKey repositoryName) throws IOException {
    checkLoaded();
    ObjectId noteId = computeRepositorySha1(repositoryName);
    if (!noteMap.contains(noteId)) {
      return ImmutableSortedSet.of();
    }

    try (RevWalk rw = new RevWalk(repo)) {
      ObjectId noteDataId = noteMap.get(noteId);
      byte[] raw = readNoteData(rw, noteDataId);
      return parseCheckerUuidsFromNote(noteId, raw, noteDataId);
    }
  }

  /**
   * Inserts a new checker for a repository.
   *
   * <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 CheckersByRepositoryNotes}.
   *
   * @param checkerUuid the UUID of the checker that should be inserted for the given repository
   * @param repositoryName the name of the repository for which the checker should be inserted
   */
  public void insert(CheckerUuid checkerUuid, Project.NameKey repositoryName) {
    checkLoaded();

    noteMapUpdates.add(
        (rw, n, f) -> {
          insert(rw, inserter, n, f, checkerUuid, repositoryName);
        });
  }

  /**
   * Removes a checker from a repository.
   *
   * <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 CheckersByRepositoryNotes}.
   *
   * @param checkerUuid the UUID of the checker that should be removed from the given repository
   * @param repositoryName the name of the repository for which the checker should be removed
   */
  public void remove(CheckerUuid checkerUuid, Project.NameKey repositoryName) {
    checkLoaded();

    noteMapUpdates.add(
        (rw, n, f) -> {
          remove(rw, inserter, n, f, checkerUuid, repositoryName);
        });
  }

  /**
   * Updates the repository for a checker.
   *
   * <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 CheckersByRepositoryNotes}.
   *
   * @param checkerUuid the UUID of the checker that should be removed from the given repository
   * @param oldRepositoryName the name of the repository for which the checker should be removed
   * @param newRepositoryName the name of the repository for which the checker should be inserted
   */
  public void update(
      CheckerUuid checkerUuid,
      Project.NameKey oldRepositoryName,
      Project.NameKey newRepositoryName) {
    checkLoaded();

    if (oldRepositoryName.equals(newRepositoryName)) {
      return;
    }

    noteMapUpdates.add(
        (rw, n, f) -> {
          remove(rw, inserter, n, f, checkerUuid, oldRepositoryName);
          insert(rw, inserter, n, f, checkerUuid, newRepositoryName);
        });
  }

  @Override
  protected void onLoad() throws IOException {
    logger.atFine().log("Reading checkers by repository note map");

    noteMap = revision != null ? NoteMap.read(reader, revision) : NoteMap.newEmptyMap();
  }

  private void checkLoaded() {
    checkState(noteMap != null, "Checkers by repository not loaded yet");
  }

  @Override
  protected boolean onSave(CommitBuilder commit) throws IOException {
    if (noteMapUpdates.isEmpty()) {
      return false;
    }

    logger.atFine().log("Updating checkers by repository");

    if (Strings.isNullOrEmpty(commit.getMessage())) {
      commit.setMessage("Update checkers by repository\n");
    }

    try (RevWalk rw = new RevWalk(reader)) {
      ImmutableSortedSet.Builder<String> footersBuilder = ImmutableSortedSet.naturalOrder();
      for (NoteMapUpdate noteMapUpdate : noteMapUpdates) {
        noteMapUpdate.execute(rw, noteMap, footersBuilder);
      }
      noteMapUpdates.clear();
      ImmutableSortedSet<String> footers = footersBuilder.build();
      if (!footers.isEmpty()) {
        commit.setMessage(
            footers.stream().collect(joining("\n", commit.getMessage().trim() + "\n\n", "")));
      }

      RevTree oldTree = revision != null ? rw.parseTree(revision) : null;
      ObjectId newTreeId = noteMap.writeTree(inserter);
      if (newTreeId.equals(oldTree)) {
        return false;
      }

      commit.setTreeId(newTreeId);
      return true;
    }
  }

  private static byte[] readNoteData(RevWalk rw, ObjectId noteDataId) throws IOException {
    return rw.getObjectReader().open(noteDataId, OBJ_BLOB).getCachedBytes(MAX_NOTE_SZ);
  }

  /**
   * Parses a list of checker UUIDs from a byte array that contain the checker UUIDs as a plain text
   * with one checker UUID per line:
   *
   * <pre>
   * e021147da7713263c46d3126b77a863930ff555b
   * e497b37e55074b7a11832a7e2d18c44b4dab8017
   * 8cc1d2415fd4fc78b7d5cc02ac59ee3939d0e1da
   * </pre>
   *
   * <p>Invalid checker UUIDs are silently ignored.
   */
  private static ImmutableSortedSet<CheckerUuid> parseCheckerUuidsFromNote(
      ObjectId noteId, byte[] raw, ObjectId blobId) {
    ImmutableSortedSet<String> lines = parseNote(raw);
    ImmutableSortedSet.Builder<CheckerUuid> checkerUuids = ImmutableSortedSet.naturalOrder();
    lines.forEach(
        line -> {
          Optional<CheckerUuid> checkerUuid = CheckerUuid.tryParse(line);
          if (checkerUuid.isPresent()) {
            checkerUuids.add(checkerUuid.get());
          } else {
            logger.atWarning().log(
                "Ignoring invalid checker UUID %s in note %s with blob ID %s.",
                line, noteId.name(), blobId.name());
          }
        });
    return checkerUuids.build();
  }

  /**
   * Parses all entries from a note, one entry per line.
   *
   * <p>Doesn't validate the entries are valid checker UUIDs.
   */
  private static ImmutableSortedSet<String> parseNote(byte[] raw) {
    return Splitter.on('\n').splitToList(new String(raw, UTF_8)).stream()
        .collect(toImmutableSortedSet(naturalOrder()));
  }

  /**
   * Insert a checker UUID for a repository and updates the note map.
   *
   * <p>No-op if the checker UUID is already recorded for the repository.
   */
  private static void insert(
      RevWalk rw,
      ObjectInserter ins,
      NoteMap noteMap,
      ImmutableSortedSet.Builder<String> footers,
      CheckerUuid checkerUuid,
      Project.NameKey repositoryName)
      throws IOException {
    String checkerUuidStr = checkerUuid.get();
    ObjectId noteId = computeRepositorySha1(repositoryName);
    ImmutableSortedSet.Builder<String> newLinesBuilder = ImmutableSortedSet.naturalOrder();
    if (noteMap.contains(noteId)) {
      ObjectId noteDataId = noteMap.get(noteId);
      byte[] raw = readNoteData(rw, noteDataId);
      ImmutableSortedSet<String> oldLines = parseNote(raw);
      if (oldLines.contains(checkerUuidStr)) {
        return;
      }
      newLinesBuilder.addAll(oldLines);
    }

    newLinesBuilder.add(checkerUuidStr);
    byte[] raw = Joiner.on("\n").join(newLinesBuilder.build()).getBytes(UTF_8);
    ObjectId noteData = ins.insert(OBJ_BLOB, raw);
    noteMap.set(noteId, noteData);
    addFooters(footers, checkerUuid, repositoryName);
  }

  /**
   * Removes a checker UUID from a repository and updates the note map.
   *
   * <p>No-op if the checker UUID is already not recorded for the repository.
   */
  private static void remove(
      RevWalk rw,
      ObjectInserter ins,
      NoteMap noteMap,
      ImmutableSortedSet.Builder<String> footers,
      CheckerUuid checkerUuid,
      Project.NameKey repositoryName)
      throws IOException {
    String checkerUuidStr = checkerUuid.get();
    ObjectId noteId = computeRepositorySha1(repositoryName);
    ImmutableSortedSet.Builder<String> newLinesBuilder = ImmutableSortedSet.naturalOrder();
    if (noteMap.contains(noteId)) {
      ObjectId noteDataId = noteMap.get(noteId);
      byte[] raw = readNoteData(rw, noteDataId);
      ImmutableSortedSet<String> oldLines = parseNote(raw);
      if (!oldLines.contains(checkerUuidStr)) {
        return;
      }
      oldLines.stream().filter(line -> !line.equals(checkerUuidStr)).forEach(newLinesBuilder::add);
    }

    ImmutableSortedSet<String> newLines = newLinesBuilder.build();
    if (newLines.isEmpty()) {
      noteMap.remove(noteId);
      return;
    }

    byte[] raw = Joiner.on("\n").join(newLines).getBytes(UTF_8);
    ObjectId noteData = ins.insert(OBJ_BLOB, raw);
    noteMap.set(noteId, noteData);
    addFooters(footers, checkerUuid, repositoryName);
  }

  private static void addFooters(
      ImmutableSortedSet.Builder<String> footers,
      CheckerUuid checkerUuid,
      Project.NameKey repositoryName) {
    footers.add("Repository: " + repositoryName.get());
    footers.add("Checker: " + checkerUuid);
  }

  /**
   * Returns the SHA1 of the repository that is used as note ID in the {@code refs/meta/checkers}
   * notes branch.
   *
   * @param repositoryName the name of the repository for which the SHA1 should be computed and
   *     returned
   * @return SHA1 for the given repository name
   */
  @VisibleForTesting
  @SuppressWarnings("deprecation") // Use Hashing.sha1 for compatibility.
  public static ObjectId computeRepositorySha1(Project.NameKey repositoryName) {
    return ObjectId.fromRaw(Hashing.sha1().hashString(repositoryName.get(), UTF_8).asBytes());
  }

  @FunctionalInterface
  private interface NoteMapUpdate {
    void execute(RevWalk rw, NoteMap noteMap, ImmutableSortedSet.Builder<String> footers)
        throws IOException;
  }
}
