// 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;
        }
        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.
   * @throws IOException
   * @throws ConfigInvalidException
   */
  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);
  }
}
