// 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.account;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gerrit.server.experiments.ExperimentFeaturesConstants.GERRIT_BACKEND_REQUEST_FEATURE_COMPUTE_FROM_ALL_USERS_REPOSITORY;

import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.accounts.DeleteDraftCommentsInput;
import com.google.gerrit.extensions.api.accounts.DeletedDraftCommentInfo;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
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.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.change.ChangeJson;
import com.google.gerrit.server.experiments.ExperimentFeatures;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangePredicates;
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.restapi.change.CommentJson;
import com.google.gerrit.server.restapi.change.CommentJson.HumanCommentFormatter;
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.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Singleton
public class DeleteDraftComments
    implements RestModifyView<AccountResource, DeleteDraftCommentsInput> {

  private final Provider<CurrentUser> userProvider;
  private final BatchUpdate.Factory batchUpdateFactory;
  private final Provider<ChangeQueryBuilder> queryBuilderProvider;
  private final Provider<InternalChangeQuery> queryProvider;
  private final ChangeData.Factory changeDataFactory;
  private final ChangeJson.Factory changeJsonFactory;
  private final Provider<CommentJson> commentJsonProvider;
  private final CommentsUtil commentsUtil;
  private final PatchSetUtil psUtil;
  private final ExperimentFeatures experimentFeatures;

  @Inject
  DeleteDraftComments(
      Provider<CurrentUser> userProvider,
      BatchUpdate.Factory batchUpdateFactory,
      Provider<ChangeQueryBuilder> queryBuilderProvider,
      Provider<InternalChangeQuery> queryProvider,
      ChangeData.Factory changeDataFactory,
      ChangeJson.Factory changeJsonFactory,
      Provider<CommentJson> commentJsonProvider,
      CommentsUtil commentsUtil,
      PatchSetUtil psUtil,
      ExperimentFeatures experimentFeatures) {
    this.userProvider = userProvider;
    this.batchUpdateFactory = batchUpdateFactory;
    this.queryBuilderProvider = queryBuilderProvider;
    this.queryProvider = queryProvider;
    this.changeDataFactory = changeDataFactory;
    this.changeJsonFactory = changeJsonFactory;
    this.commentJsonProvider = commentJsonProvider;
    this.commentsUtil = commentsUtil;
    this.psUtil = psUtil;
    this.experimentFeatures = experimentFeatures;
  }

  @Override
  public Response<ImmutableList<DeletedDraftCommentInfo>> apply(
      AccountResource rsrc, DeleteDraftCommentsInput input)
      throws RestApiException, UpdateException {
    CurrentUser user = userProvider.get();
    if (!user.isIdentifiedUser()) {
      throw new AuthException("Authentication required");
    }
    if (!rsrc.getUser().hasSameAccountId(user)) {
      // Disallow even for admins or users with Modify Account. Drafts are not like preferences or
      // other account info; there is no way even for admins to read or delete another user's drafts
      // using the normal draft endpoints under the change resource, so disallow it here as well.
      // (Admins may still call this endpoint with impersonation, but in that case it would pass the
      // hasSameAccountId check.)
      throw new AuthException("Cannot delete drafts of other user");
    }

    HumanCommentFormatter humanCommentFormatter =
        commentJsonProvider.get().newHumanCommentFormatter();
    Account.Id accountId = rsrc.getUser().getAccountId();
    Instant now = TimeUtil.now();
    Map<Project.NameKey, BatchUpdate> updates = new LinkedHashMap<>();
    List<Op> ops = new ArrayList<>();
    for (ChangeData cd :
        queryProvider
            .get()
            // Don't attempt to mutate any changes the user can't currently see.
            .enforceVisibility(true)
            .query(predicate(accountId, input))) {
      BatchUpdate update =
          updates.computeIfAbsent(
              cd.project(), p -> batchUpdateFactory.create(p, rsrc.getUser(), now));
      Op op = new Op(humanCommentFormatter, accountId);
      update.addOp(cd.getId(), op);
      ops.add(op);
    }

    // Currently there's no way to let some updates succeed even if others fail. Even if there were,
    // all updates from this operation only happen in All-Users and thus are fully atomic, so
    // allowing partial failure would have little value.
    BatchUpdate.execute(updates.values(), ImmutableList.of(), false);

    return Response.ok(
        ops.stream().map(Op::getResult).filter(Objects::nonNull).collect(toImmutableList()));
  }

  private Predicate<ChangeData> predicate(Account.Id accountId, DeleteDraftCommentsInput input)
      throws BadRequestException {
    Predicate<ChangeData> hasDraft =
        ChangePredicates.draftBy(
            experimentFeatures.isFeatureEnabled(
                GERRIT_BACKEND_REQUEST_FEATURE_COMPUTE_FROM_ALL_USERS_REPOSITORY),
            commentsUtil,
            accountId);
    if (CharMatcher.whitespace().trimFrom(Strings.nullToEmpty(input.query)).isEmpty()) {
      return hasDraft;
    }
    try {
      return Predicate.and(hasDraft, queryBuilderProvider.get().parse(input.query));
    } catch (QueryParseException e) {
      throw new BadRequestException("Invalid query: " + e.getMessage(), e);
    }
  }

  private class Op implements BatchUpdateOp {
    private final HumanCommentFormatter humanCommentFormatter;
    private final Account.Id accountId;
    private DeletedDraftCommentInfo result;

    Op(HumanCommentFormatter humanCommentFormatter, Account.Id accountId) {
      this.humanCommentFormatter = humanCommentFormatter;
      this.accountId = accountId;
    }

    @Override
    public boolean updateChange(ChangeContext ctx) throws PermissionBackendException {
      ImmutableList.Builder<CommentInfo> comments = ImmutableList.builder();
      boolean dirty = false;
      for (HumanComment c : commentsUtil.draftByChangeAuthor(ctx.getNotes(), accountId)) {
        dirty = true;
        PatchSet.Id psId = PatchSet.id(ctx.getChange().getId(), c.key.patchSetId);
        commentsUtil.setCommentCommitId(c, ctx.getChange(), psUtil.get(ctx.getNotes(), psId));
        commentsUtil.deleteHumanComments(ctx.getUpdate(psId), Collections.singleton(c));
        comments.add(humanCommentFormatter.format(c));
      }
      if (dirty) {
        result = new DeletedDraftCommentInfo();
        result.change =
            changeJsonFactory.noOptions().format(changeDataFactory.create(ctx.getNotes()));
        result.deleted = comments.build();
      }
      return dirty;
    }

    @Nullable
    DeletedDraftCommentInfo getResult() {
      return result;
    }
  }
}
