// 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 com.google.common.base.Preconditions.checkNotNull;
import static com.google.gerrit.server.ChangeMessagesUtil.createChangeMessageInfo;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.gerrit.common.Nullable;
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.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
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.RetryHelper;
import com.google.gerrit.server.update.RetryingRestModifyView;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gwtorm.server.OrmException;
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
    extends RetryingRestModifyView<
        ChangeMessageResource, DeleteChangeMessageInput, Response<ChangeMessageInfo>> {

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

  @Inject
  public DeleteChangeMessage(
      Provider<CurrentUser> userProvider,
      Provider<ReviewDb> dbProvider,
      PermissionBackend permissionBackend,
      ChangeMessagesUtil changeMessagesUtil,
      AccountLoader.Factory accountLoaderFactory,
      ChangeNotes.Factory notesFactory,
      RetryHelper retryHelper) {
    super(retryHelper);
    this.userProvider = userProvider;
    this.dbProvider = dbProvider;
    this.permissionBackend = permissionBackend;
    this.changeMessagesUtil = changeMessagesUtil;
    this.accountLoaderFactory = accountLoaderFactory;
    this.notesFactory = notesFactory;
  }

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

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

    ChangeMessageInfo updatedMessageInfo =
        createUpdatedChangeMessageInfo(resource.getChangeId(), resource.getChangeMessageIndex());
    return Response.created(updatedMessageInfo);
  }

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

  @VisibleForTesting
  public static String createNewChangeMessage(String deletedBy, @Nullable String deletedReason) {
    checkNotNull(deletedBy, "user name must not be null");

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

  @VisibleForTesting
  public static String createNewChangeMessage(String deletedBy) {
    checkNotNull(deletedBy, "user name must not be null");

    return "Change message removed by: " + deletedBy;
  }

  private class DeleteChangeMessageOp implements BatchUpdateOp {
    private final int targetMessageIdx;
    private final String newMessage;

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

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

  @Singleton
  public static class DefaultDeleteChangeMessage
      extends RetryingRestModifyView<ChangeMessageResource, Input, Response<ChangeMessageInfo>> {
    private final DeleteChangeMessage deleteChangeMessage;

    @Inject
    public DefaultDeleteChangeMessage(
        DeleteChangeMessage deleteChangeMessage, RetryHelper retryHelper) {
      super(retryHelper);
      this.deleteChangeMessage = deleteChangeMessage;
    }

    @Override
    protected Response<ChangeMessageInfo> applyImpl(
        BatchUpdate.Factory updateFactory, ChangeMessageResource resource, Input input)
        throws Exception {
      return deleteChangeMessage.applyImpl(updateFactory, resource, new DeleteChangeMessageInput());
    }
  }
}
