// Copyright (C) 2017 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.Preconditions.checkArgument;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;

import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.RefNames;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
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.ObjectReader;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * Deletes a published comment from NoteDb by rewriting the commit history. Instead of deleting the
 * whole comment, it just replaces the comment's message with a new message.
 */
public class DeleteCommentRewriter implements NoteDbRewriter {

  public interface Factory {
    /**
     * Creates a DeleteCommentRewriter instance.
     *
     * @param id the id of the change which contains the target comment.
     * @param uuid the uuid of the target comment.
     * @param newMessage the message used to replace the old message of the target comment.
     * @return the DeleteCommentRewriter instance
     */
    DeleteCommentRewriter create(
        Change.Id id, @Assisted("uuid") String uuid, @Assisted("newMessage") String newMessage);
  }

  private final ChangeNoteUtil noteUtil;
  private final Change.Id changeId;
  private final String uuid;
  private final String newMessage;

  @Inject
  DeleteCommentRewriter(
      ChangeNoteUtil noteUtil,
      @Assisted Change.Id changeId,
      @Assisted("uuid") String uuid,
      @Assisted("newMessage") String newMessage) {
    this.noteUtil = noteUtil;
    this.changeId = changeId;
    this.uuid = uuid;
    this.newMessage = newMessage;
  }

  @Override
  public String getRefName() {
    return RefNames.changeMetaRef(changeId);
  }

  @Override
  public ObjectId rewriteCommitHistory(RevWalk revWalk, ObjectInserter inserter, ObjectId currTip)
      throws IOException, ConfigInvalidException {
    checkArgument(!currTip.equals(ObjectId.zeroId()));

    // Walk from the first commit of the branch.
    revWalk.reset();
    revWalk.markStart(revWalk.parseCommit(currTip));
    revWalk.sort(RevSort.REVERSE);

    ObjectReader reader = revWalk.getObjectReader();
    RevCommit newTipCommit = revWalk.next(); // The first commit will not be rewritten.
    Map<String, HumanComment> parentComments =
        getPublishedComments(noteUtil, reader, NoteMap.read(reader, newTipCommit));

    boolean rewrite = false;
    RevCommit originalCommit;
    while ((originalCommit = revWalk.next()) != null) {
      NoteMap noteMap = NoteMap.read(reader, originalCommit);
      Map<String, HumanComment> currComments = getPublishedComments(noteUtil, reader, noteMap);

      if (!rewrite && currComments.containsKey(uuid)) {
        rewrite = true;
      }

      if (!rewrite) {
        parentComments = currComments;
        newTipCommit = originalCommit;
        continue;
      }

      List<HumanComment> putInComments = getPutInComments(parentComments, currComments);
      List<HumanComment> deletedComments = getDeletedComments(parentComments, currComments);
      newTipCommit =
          revWalk.parseCommit(
              rewriteCommit(
                  originalCommit, newTipCommit, inserter, reader, putInComments, deletedComments));
      parentComments = currComments;
    }

    return newTipCommit;
  }

  /**
   * Gets all the comments which are presented at a commit. Note they include the comments put in by
   * the previous commits.
   */
  @VisibleForTesting
  public static Map<String, HumanComment> getPublishedComments(
      ChangeNoteJson changeNoteJson, ObjectReader reader, NoteMap noteMap)
      throws IOException, ConfigInvalidException {
    return RevisionNoteMap.parse(changeNoteJson, reader, noteMap, HumanComment.Status.PUBLISHED)
        .revisionNotes.values().stream()
        .flatMap(n -> n.getEntities().stream())
        .collect(toMap(c -> c.key.uuid, Function.identity()));
  }

  public static Map<String, HumanComment> getPublishedComments(
      ChangeNoteUtil noteUtil, ObjectReader reader, NoteMap noteMap)
      throws IOException, ConfigInvalidException {
    return getPublishedComments(noteUtil.getChangeNoteJson(), reader, noteMap);
  }
  /**
   * Gets the comments put in by the current commit. The message of the target comment will be
   * replaced by the new message.
   *
   * @param parMap the comment map of the parent commit.
   * @param curMap the comment map of the current commit.
   * @return The comments put in by the current commit.
   */
  private List<HumanComment> getPutInComments(
      Map<String, HumanComment> parMap, Map<String, HumanComment> curMap) {
    List<HumanComment> comments = new ArrayList<>();
    for (String key : curMap.keySet()) {
      if (!parMap.containsKey(key)) {
        HumanComment comment = curMap.get(key);
        if (key.equals(uuid)) {
          comment.message = newMessage;
          comment.unresolved = false;
        }
        comments.add(comment);
      }
    }
    return comments;
  }

  /**
   * Gets the comments deleted by the current commit.
   *
   * @param parMap the comment map of the parent commit.
   * @param curMap the comment map of the current commit.
   * @return The comments deleted by the current commit.
   */
  private List<HumanComment> getDeletedComments(
      Map<String, HumanComment> parMap, Map<String, HumanComment> curMap) {
    return parMap.entrySet().stream()
        .filter(c -> !curMap.containsKey(c.getKey()))
        .map(Map.Entry::getValue)
        .collect(toList());
  }

  /**
   * Rewrites one commit.
   *
   * @param originalCommit the original commit to be rewritten.
   * @param parentCommit the parent of the new commit.
   * @param inserter the {@code ObjectInserter} for the rewrite process.
   * @param reader the {@code ObjectReader} for the rewrite process.
   * @param putInComments the comments put in by this commit.
   * @param deletedComments the comments deleted by this commit.
   * @return the {@code objectId} of the new commit.
   */
  private ObjectId rewriteCommit(
      RevCommit originalCommit,
      RevCommit parentCommit,
      ObjectInserter inserter,
      ObjectReader reader,
      List<HumanComment> putInComments,
      List<HumanComment> deletedComments)
      throws IOException, ConfigInvalidException {
    RevisionNoteMap<ChangeRevisionNote> revNotesMap =
        RevisionNoteMap.parse(
            noteUtil.getChangeNoteJson(),
            reader,
            NoteMap.read(reader, parentCommit),
            HumanComment.Status.PUBLISHED);
    RevisionNoteBuilder.Cache cache = new RevisionNoteBuilder.Cache(revNotesMap);

    for (HumanComment c : putInComments) {
      cache.get(c.getCommitId()).putComment(c);
    }

    for (HumanComment c : deletedComments) {
      cache.get(c.getCommitId()).deleteComment(c.key);
    }

    Map<ObjectId, RevisionNoteBuilder> builders = cache.getBuilders();
    for (Map.Entry<ObjectId, RevisionNoteBuilder> entry : builders.entrySet()) {
      ObjectId objectId = entry.getKey();
      byte[] data = entry.getValue().build(noteUtil.getChangeNoteJson());
      if (data.length == 0) {
        revNotesMap.noteMap.remove(objectId);
      } else {
        revNotesMap.noteMap.set(objectId, inserter.insert(OBJ_BLOB, data));
      }
    }

    CommitBuilder cb = new CommitBuilder();
    cb.setParentId(parentCommit);
    cb.setTreeId(revNotesMap.noteMap.writeTree(inserter));
    cb.setMessage(originalCommit.getFullMessage());
    cb.setCommitter(originalCommit.getCommitterIdent());
    cb.setAuthor(originalCommit.getAuthorIdent());
    cb.setEncoding(originalCommit.getEncoding());

    return inserter.insert(cb);
  }
}
