// Copyright (C) 2018 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.restapi.change;

import static java.util.Objects.requireNonNull;

import com.google.common.base.Strings;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.changes.DeleteChangeMessageInput;
import com.google.gerrit.extensions.common.ChangeMessageInfo;
import com.google.gerrit.extensions.common.Input;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.change.ChangeMessageResource;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.List;

/** Deletes a change message by rewriting history. */
@Singleton
public class DeleteChangeMessage
    implements RestModifyView<ChangeMessageResource, DeleteChangeMessageInput> {

  private final Provider<CurrentUser> userProvider;
  private final PermissionBackend permissionBackend;
  private final BatchUpdate.Factory updateFactory;
  private final ChangeMessagesUtil changeMessagesUtil;
  private final AccountLoader.Factory accountLoaderFactory;
  private final ChangeNotes.Factory notesFactory;

  @Inject
  public DeleteChangeMessage(
      Provider<CurrentUser> userProvider,
      PermissionBackend permissionBackend,
      BatchUpdate.Factory updateFactory,
      ChangeMessagesUtil changeMessagesUtil,
      AccountLoader.Factory accountLoaderFactory,
      ChangeNotes.Factory notesFactory) {
    this.userProvider = userProvider;
    this.permissionBackend = permissionBackend;
    this.updateFactory = updateFactory;
    this.changeMessagesUtil = changeMessagesUtil;
    this.accountLoaderFactory = accountLoaderFactory;
    this.notesFactory = notesFactory;
  }

  @Override
  public Response<ChangeMessageInfo> apply(
      ChangeMessageResource resource, DeleteChangeMessageInput input)
      throws RestApiException, PermissionBackendException, UpdateException, IOException {
    CurrentUser user = userProvider.get();
    permissionBackend.user(user).check(GlobalPermission.ADMINISTRATE_SERVER);

    String newChangeMessage =
        createNewChangeMessage(user.asIdentifiedUser().getAccountId(), input.reason);
    DeleteChangeMessageOp deleteChangeMessageOp =
        new DeleteChangeMessageOp(resource.getChangeMessageId(), newChangeMessage);
    try (BatchUpdate batchUpdate =
        updateFactory.create(resource.getChangeResource().getProject(), user, TimeUtil.nowTs())) {
      batchUpdate.addOp(resource.getChangeId(), deleteChangeMessageOp).execute();
    }

    ChangeMessageInfo updatedMessageInfo =
        createUpdatedChangeMessageInfo(
            resource.getChangeResource().getId(),
            resource.getChangeResource().getProject(),
            resource.getChangeMessageIndex());
    return Response.created(updatedMessageInfo);
  }

  private ChangeMessageInfo createUpdatedChangeMessageInfo(
      Change.Id cId, Project.NameKey project, int targetIdx) throws PermissionBackendException {
    List<ChangeMessage> messages =
        changeMessagesUtil.byChange(notesFactory.createChecked(project, cId));
    ChangeMessage updatedChangeMessage = messages.get(targetIdx);
    AccountLoader accountLoader = accountLoaderFactory.create(true);
    ChangeMessageInfo info =
        changeMessagesUtil.createChangeMessageInfoWithReplacedTemplates(
            updatedChangeMessage, accountLoader);
    accountLoader.fill();
    return info;
  }

  public static String createNewChangeMessage(
      Account.Id deletedBy, @Nullable String deletedReason) {
    requireNonNull(deletedBy, "user must not be null");

    if (Strings.isNullOrEmpty(deletedReason)) {
      return createNewChangeMessage(deletedBy);
    }
    return String.format(
        "Change message removed by: %s\nReason: %s",
        ChangeMessagesUtil.getAccountTemplate(deletedBy), deletedReason);
  }

  public static String createNewChangeMessage(Account.Id deletedBy) {
    requireNonNull(deletedBy, "user must not be null");

    return "Change message removed by: " + ChangeMessagesUtil.getAccountTemplate(deletedBy);
  }

  private class DeleteChangeMessageOp implements BatchUpdateOp {
    private final String targetMessageId;
    private final String newMessage;

    DeleteChangeMessageOp(String targetMessageIdx, String newMessage) {
      this.targetMessageId = targetMessageIdx;
      this.newMessage = newMessage;
    }

    @Override
    public boolean updateChange(ChangeContext ctx) {
      PatchSet.Id psId = ctx.getChange().currentPatchSetId();
      changeMessagesUtil.replaceChangeMessage(ctx.getUpdate(psId), targetMessageId, newMessage);
      return true;
    }
  }

  @Singleton
  public static class DefaultDeleteChangeMessage
      implements RestModifyView<ChangeMessageResource, Input> {
    private final DeleteChangeMessage deleteChangeMessage;

    @Inject
    public DefaultDeleteChangeMessage(DeleteChangeMessage deleteChangeMessage) {
      this.deleteChangeMessage = deleteChangeMessage;
    }

    @Override
    public Response<ChangeMessageInfo> apply(ChangeMessageResource resource, Input input)
        throws RestApiException, PermissionBackendException, UpdateException, IOException {
      return deleteChangeMessage.apply(resource, new DeleteChangeMessageInput());
    }
  }
}
