// Copyright (C) 2013 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.acceptance.rest.change;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.extensions.client.ListChangesOption.MESSAGES;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.parseCommitMessageRange;
import static com.google.gerrit.server.restapi.change.DeleteChangeMessage.createNewChangeMessage;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toSet;
import static org.eclipse.jgit.util.RawParseUtils.decode;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.UseClockStep;
import com.google.gerrit.acceptance.UseTimezone;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.entities.Change;
import com.google.gerrit.extensions.api.changes.DeleteChangeMessageInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeMessageInfo;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.server.notedb.ChangeNoteUtil;
import com.google.inject.Inject;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.util.RawParseUtils;
import org.junit.Test;

@UseClockStep
@UseTimezone(timezone = "US/Eastern")
public class ChangeMessagesIT extends AbstractDaemonTest {
  @Inject private ProjectOperations projectOperations;
  @Inject private RequestScopeOperations requestScopeOperations;

  @Test
  public void messagesNotReturnedByDefault() throws Exception {
    String changeId = createChange().getChangeId();
    postMessage(changeId, "Some nits need to be fixed.");
    ChangeInfo c = info(changeId);
    assertThat(c.messages).isNull();
  }

  @Test
  public void defaultMessage() throws Exception {
    String changeId = createChange().getChangeId();
    ChangeInfo c = get(changeId, MESSAGES);
    assertThat(c.messages).isNotNull();
    assertThat(c.messages).hasSize(1);
    assertThat(c.messages.iterator().next().message).isEqualTo("Uploaded patch set 1.");
  }

  @Test
  public void messagesReturnedInChronologicalOrder() throws Exception {
    String changeId = createChange().getChangeId();
    String firstMessage = "Some nits need to be fixed.";
    postMessage(changeId, firstMessage);
    String secondMessage = "I like this feature.";
    postMessage(changeId, secondMessage);
    ChangeInfo c = get(changeId, MESSAGES);
    assertThat(c.messages).isNotNull();
    assertThat(c.messages).hasSize(3);
    Iterator<ChangeMessageInfo> it = c.messages.iterator();
    assertThat(it.next().message).isEqualTo("Uploaded patch set 1.");
    assertMessage(firstMessage, it.next().message);
    assertMessage(secondMessage, it.next().message);
  }

  @Test
  public void postMessageWithTag() throws Exception {
    String changeId = createChange().getChangeId();
    String tag = "jenkins";
    String msg = "Message with tag.";
    postMessage(changeId, msg, tag);
    ChangeInfo c = get(changeId, MESSAGES);
    assertThat(c.messages).isNotNull();
    assertThat(c.messages).hasSize(2);
    Iterator<ChangeMessageInfo> it = c.messages.iterator();
    assertThat(it.next().message).isEqualTo("Uploaded patch set 1.");
    ChangeMessageInfo actual = it.next();
    assertMessage(msg, actual.message);
    assertThat(actual.tag).isEqualTo(tag);
  }

  @Test
  public void listChangeMessages() throws Exception {
    int changeNum = createOneChangeWithMultipleChangeMessagesInHistory();
    List<ChangeMessageInfo> messages1 = gApi.changes().id(changeNum).messages();
    List<ChangeMessageInfo> messages2 =
        new ArrayList<>(gApi.changes().id(changeNum).get().messages);
    assertThat(messages1).containsExactlyElementsIn(messages2).inOrder();
  }

  @Test
  public void listChangeMessagesSkippedEmpty() throws Exception {
    // Change message 1: create a change.
    PushOneCommit.Result result = createChange();
    String changeId = result.getChangeId();
    // Will be a new commit with empty change message on the meta branch.
    addOneReviewWithEmptyChangeMessage(changeId);
    // Change Message 2: post a review with message "message 1".
    addOneReview(changeId, "message");

    List<ChangeMessageInfo> messages = gApi.changes().id(changeId).messages();
    assertThat(messages).hasSize(2);
  }

  @Test
  public void getOneChangeMessage() throws Exception {
    int changeNum = createOneChangeWithMultipleChangeMessagesInHistory();
    List<ChangeMessageInfo> messages = new ArrayList<>(gApi.changes().id(changeNum).get().messages);
    for (ChangeMessageInfo messageInfo : messages) {
      String id = messageInfo.id;
      assertThat(gApi.changes().id(changeNum).message(id).get()).isEqualTo(messageInfo);
    }
  }

  @Test
  public void deleteCannotBeAppliedWithoutAdministrateServerCapability() throws Exception {
    int changeNum = createOneChangeWithMultipleChangeMessagesInHistory();
    requestScopeOperations.setApiUser(user.id());

    AuthException thrown =
        assertThrows(AuthException.class, () -> deleteOneChangeMessage(changeNum, 0, user, "spam"));
    assertThat(thrown).hasMessageThat().isEqualTo("administrate server not permitted");
  }

  @Test
  public void deleteCanBeAppliedWithAdministrateServerCapability() throws Exception {
    projectOperations
        .allProjectsForUpdate()
        .add(allowCapability(GlobalCapability.ADMINISTRATE_SERVER).group(REGISTERED_USERS))
        .update();
    int changeNum = createOneChangeWithMultipleChangeMessagesInHistory();
    requestScopeOperations.setApiUser(user.id());
    deleteOneChangeMessage(changeNum, 0, user, "spam");
  }

  @Test
  public void deleteCannotBeAppliedWithEmptyChangeMessageUuid() throws Exception {
    String changeId = createChange().getChangeId();

    ResourceNotFoundException thrown =
        assertThrows(
            ResourceNotFoundException.class,
            () ->
                gApi.changes()
                    .id(changeId)
                    .message("")
                    .delete(new DeleteChangeMessageInput("spam")));
    assertThat(thrown).hasMessageThat().isEqualTo("change message  not found");
  }

  @Test
  public void deleteCannotBeAppliedWithNonExistingChangeMessageUuid() throws Exception {
    String changeId = createChange().getChangeId();
    DeleteChangeMessageInput input = new DeleteChangeMessageInput();
    String id = "8473b95934b5732ac55d26311a706c9c2bde9941";
    input.reason = "spam";

    ResourceNotFoundException thrown =
        assertThrows(
            ResourceNotFoundException.class,
            () -> gApi.changes().id(changeId).message(id).delete(input));
    assertThat(thrown).hasMessageThat().isEqualTo(String.format("change message %s not found", id));
  }

  @Test
  public void deleteCanBeAppliedWithoutProvidingReason() throws Exception {
    int changeNum = createOneChangeWithMultipleChangeMessagesInHistory();
    deleteOneChangeMessage(changeNum, 2, admin, "");
  }

  @Test
  public void deleteOneChangeMessageTwice() throws Exception {
    int changeNum = createOneChangeWithMultipleChangeMessagesInHistory();
    // Deletes the second change message twice.
    deleteOneChangeMessage(changeNum, 1, admin, "reason 1");
    deleteOneChangeMessage(changeNum, 1, admin, "reason 2");
  }

  @Test
  public void deleteMultipleChangeMessages() throws Exception {
    int changeNum = createOneChangeWithMultipleChangeMessagesInHistory();
    for (int i = 0; i < 7; ++i) {
      deleteOneChangeMessage(changeNum, i, admin, "reason " + i);
    }
  }

  private int createOneChangeWithMultipleChangeMessagesInHistory() throws Exception {
    // Creates the following commit history on the meta branch of the test change.

    requestScopeOperations.setApiUser(user.id());
    // Commit 1: create a change.
    PushOneCommit.Result result = createChange();
    String changeId = result.getChangeId();
    // Commit 2: post an empty change message.
    requestScopeOperations.setApiUser(admin.id());
    addOneReviewWithEmptyChangeMessage(changeId);
    // Commit 3: post a review with message "message 1".
    addOneReview(changeId, "message 1");
    // Commit 4: amend a new patch set.
    requestScopeOperations.setApiUser(user.id());
    amendChange(changeId);
    // Commit 5: post a review with message "message 2".
    addOneReview(changeId, "message 2");
    // Commit 6: amend a new patch set.
    amendChange(changeId);
    // Commit 7: approve the change.
    requestScopeOperations.setApiUser(admin.id());
    gApi.changes().id(changeId).current().review(ReviewInput.approve());
    // commit 8: submit the change.
    gApi.changes().id(changeId).current().submit();

    // Verifies there is only 7 change messages although there are 8 commits.
    List<ChangeMessageInfo> messages = gApi.changes().id(changeId).messages();
    assertThat(messages).hasSize(7);

    return result.getChange().getId().get();
  }

  private void addOneReview(String changeId, String changeMessage) throws Exception {
    ReviewInput.CommentInput c = new ReviewInput.CommentInput();
    c.line = 1;
    c.message = "comment 1";
    c.path = FILE_NAME;

    ReviewInput reviewInput = new ReviewInput().label("Code-Review", 1);
    reviewInput.comments = ImmutableMap.of(c.path, Lists.newArrayList(c));
    reviewInput.message = changeMessage;

    gApi.changes().id(changeId).current().review(reviewInput);
  }

  private void addOneReviewWithEmptyChangeMessage(String changeId) throws Exception {
    gApi.changes().id(changeId).current().review(new ReviewInput());
  }

  private void deleteOneChangeMessage(
      int changeNum, int deletedMessageIndex, TestAccount deletedBy, String reason)
      throws Exception {
    List<ChangeMessageInfo> messagesBeforeDeletion = gApi.changes().id(changeNum).messages();

    List<CommentInfo> commentsBefore = getChangeSortedComments(changeNum);
    List<RevCommit> commitsBefore = getChangeMetaCommitsInReverseOrder(Change.id(changeNum));

    String id = messagesBeforeDeletion.get(deletedMessageIndex).id;
    DeleteChangeMessageInput input = new DeleteChangeMessageInput(reason);
    ChangeMessageInfo info = gApi.changes().id(changeNum).message(id).delete(input);

    // Verify the return change message info is as expect.
    assertThat(info.message).isEqualTo(createNewChangeMessage(deletedBy.fullName(), reason));
    List<ChangeMessageInfo> messagesAfterDeletion = gApi.changes().id(changeNum).messages();
    assertMessagesAfterDeletion(
        messagesBeforeDeletion, messagesAfterDeletion, deletedMessageIndex, deletedBy, reason);
    assertCommentsAfterDeletion(changeNum, commentsBefore);

    // Verify change index is updated after deletion.
    List<ChangeInfo> changes = gApi.changes().query("message removed").get();
    assertThat(changes.stream().map(c -> c._number).collect(toSet())).contains(changeNum);

    // Verifies states of commits.
    assertMetaCommitsAfterDeletion(commitsBefore, changeNum, id, deletedBy, reason);
  }

  private void assertMessagesAfterDeletion(
      List<ChangeMessageInfo> messagesBeforeDeletion,
      List<ChangeMessageInfo> messagesAfterDeletion,
      int deletedMessageIndex,
      TestAccount deletedBy,
      String deleteReason) {
    assertWithMessage("after: %s; before: %s", messagesAfterDeletion, messagesBeforeDeletion)
        .that(messagesAfterDeletion)
        .hasSize(messagesBeforeDeletion.size());

    for (int i = 0; i < messagesAfterDeletion.size(); ++i) {
      ChangeMessageInfo before = messagesBeforeDeletion.get(i);
      ChangeMessageInfo after = messagesAfterDeletion.get(i);

      if (i < deletedMessageIndex) {
        // The uuid of a commit message will be updated after rewriting.
        assertThat(after.id).isEqualTo(before.id);
      }

      assertThat(after.tag).isEqualTo(before.tag);
      assertThat(after.author).isEqualTo(before.author);
      assertThat(after.realAuthor).isEqualTo(before.realAuthor);
      assertThat(after._revisionNumber).isEqualTo(before._revisionNumber);

      if (i == deletedMessageIndex) {
        assertThat(after.message)
            .isEqualTo(createNewChangeMessage(deletedBy.fullName(), deleteReason));
      } else {
        assertThat(after.message).isEqualTo(before.message);
      }
    }
  }

  private void assertMetaCommitsAfterDeletion(
      List<RevCommit> commitsBeforeDeletion,
      int changeNum,
      String deletedMessageId,
      TestAccount deletedBy,
      String deleteReason)
      throws Exception {
    List<RevCommit> commitsAfterDeletion = getChangeMetaCommitsInReverseOrder(Change.id(changeNum));
    assertThat(commitsAfterDeletion).hasSize(commitsBeforeDeletion.size());

    for (int i = 0; i < commitsBeforeDeletion.size(); i++) {
      RevCommit commitBefore = commitsBeforeDeletion.get(i);
      RevCommit commitAfter = commitsAfterDeletion.get(i);
      if (commitBefore.getId().getName().equals(deletedMessageId)) {
        byte[] rawBefore = commitBefore.getRawBuffer();
        byte[] rawAfter = commitAfter.getRawBuffer();
        Charset encodingBefore = RawParseUtils.parseEncoding(rawBefore);
        Charset encodingAfter = RawParseUtils.parseEncoding(rawAfter);
        Optional<ChangeNoteUtil.CommitMessageRange> rangeBefore =
            parseCommitMessageRange(commitBefore);
        Optional<ChangeNoteUtil.CommitMessageRange> rangeAfter =
            parseCommitMessageRange(commitAfter);
        assertThat(rangeBefore).isPresent();
        assertThat(rangeAfter).isPresent();

        String subjectBefore =
            decode(
                encodingBefore,
                rawBefore,
                rangeBefore.get().subjectStart(),
                rangeBefore.get().subjectEnd());
        String subjectAfter =
            decode(
                encodingAfter,
                rawAfter,
                rangeAfter.get().subjectStart(),
                rangeAfter.get().subjectEnd());
        assertThat(subjectBefore).isEqualTo(subjectAfter);

        String footersBefore =
            decode(
                encodingBefore,
                rawBefore,
                rangeBefore.get().changeMessageEnd() + 1,
                rawBefore.length);
        String footersAfter =
            decode(
                encodingAfter, rawAfter, rangeAfter.get().changeMessageEnd() + 1, rawAfter.length);
        assertThat(footersBefore).isEqualTo(footersAfter);

        String message =
            decode(
                encodingAfter,
                rawAfter,
                rangeAfter.get().changeMessageStart(),
                rangeAfter.get().changeMessageEnd() + 1);
        assertThat(message).isEqualTo(createNewChangeMessage(deletedBy.fullName(), deleteReason));
      } else {
        assertThat(commitAfter.getFullMessage()).isEqualTo(commitBefore.getFullMessage());
      }

      assertThat(commitAfter.getCommitterIdent().getName())
          .isEqualTo(commitBefore.getCommitterIdent().getName());
      assertThat(commitAfter.getAuthorIdent().getName())
          .isEqualTo(commitBefore.getAuthorIdent().getName());
      assertThat(commitAfter.getEncoding()).isEqualTo(commitBefore.getEncoding());
      assertThat(commitAfter.getEncodingName()).isEqualTo(commitBefore.getEncodingName());
    }
  }

  /** Verifies comments are not changed after deleting change message(s). */
  private void assertCommentsAfterDeletion(int changeNum, List<CommentInfo> commentsBeforeDeletion)
      throws Exception {
    List<CommentInfo> commentsAfterDeletion = getChangeSortedComments(changeNum);
    assertThat(commentsAfterDeletion).containsExactlyElementsIn(commentsBeforeDeletion).inOrder();
  }

  private static void assertMessage(String expected, String actual) {
    assertThat(actual).isEqualTo("Patch Set 1:\n\n" + expected);
  }

  private void postMessage(String changeId, String msg) throws Exception {
    postMessage(changeId, msg, null);
  }

  private void postMessage(String changeId, String msg, String tag) throws Exception {
    ReviewInput in = new ReviewInput();
    in.message = msg;
    in.tag = tag;
    gApi.changes().id(changeId).current().review(in);
  }
}
