// Copyright (C) 2023 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 com.google.common.collect.ImmutableSet;
import com.google.common.collect.Table;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.common.Input;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.gpg.PublicKeyStoreUtil;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.StarredChangesUtil;
import com.google.gerrit.server.UserInitiated;
import com.google.gerrit.server.account.AccountException;
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.account.AccountSshKey;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.VersionedAuthorizedKeys;
import com.google.gerrit.server.change.AccountPatchReviewStore;
import com.google.gerrit.server.edit.ChangeEdit;
import com.google.gerrit.server.edit.ChangeEditUtil;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.plugincontext.PluginItemContext;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.ssh.SshKeyCache;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.List;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * REST endpoint for deleting an account.
 *
 * <p>This REST endpoint handles {@code DELETE /accounts/<account-identifier>} requests. Currently,
 * only self deletions are allowed.
 */
@Singleton
public class DeleteAccount implements RestModifyView<AccountResource, Input> {
  private final Provider<CurrentUser> self;
  private final Provider<PersonIdent> serverIdent;
  private final Provider<AccountsUpdate> accountsUpdateProvider;
  private final VersionedAuthorizedKeys.Accessor authorizedKeys;
  private final SshKeyCache sshKeyCache;
  private final StarredChangesUtil starredChangesUtil;
  private final DeleteDraftCommentsUtil deleteDraftCommentsUtil;
  private final GitRepositoryManager gitManager;
  private final Provider<InternalChangeQuery> queryProvider;
  private final ChangeEditUtil changeEditUtil;
  private final PluginItemContext<AccountPatchReviewStore> accountPatchReviewStore;
  private final PublicKeyStoreUtil publicKeyStoreUtil;

  @Inject
  public DeleteAccount(
      Provider<CurrentUser> self,
      @GerritPersonIdent Provider<PersonIdent> serverIdent,
      @UserInitiated Provider<AccountsUpdate> accountsUpdateProvider,
      VersionedAuthorizedKeys.Accessor authorizedKeys,
      SshKeyCache sshKeyCache,
      StarredChangesUtil starredChangesUtil,
      DeleteDraftCommentsUtil deleteDraftCommentsUtil,
      GitRepositoryManager gitManager,
      Provider<InternalChangeQuery> queryProvider,
      ChangeEditUtil changeEditUtil,
      PluginItemContext<AccountPatchReviewStore> accountPatchReviewStore,
      PublicKeyStoreUtil publicKeyStoreUtil) {
    this.self = self;
    this.serverIdent = serverIdent;
    this.accountsUpdateProvider = accountsUpdateProvider;
    this.authorizedKeys = authorizedKeys;
    this.sshKeyCache = sshKeyCache;
    this.starredChangesUtil = starredChangesUtil;
    this.deleteDraftCommentsUtil = deleteDraftCommentsUtil;
    this.gitManager = gitManager;
    this.queryProvider = queryProvider;
    this.changeEditUtil = changeEditUtil;
    this.accountPatchReviewStore = accountPatchReviewStore;
    this.publicKeyStoreUtil = publicKeyStoreUtil;
  }

  @Override
  @CanIgnoreReturnValue
  public Response<?> apply(AccountResource rsrc, Input unusedInput)
      throws AuthException, AccountException {
    IdentifiedUser user = rsrc.getUser();
    if (!self.get().hasSameAccountId(user)) {
      throw new AuthException("Delete account is only permitted for self");
    }

    Account.Id userId = user.getAccountId();
    try {
      deletePgpKeys(user);
      deleteSshKeys(user);
      deleteStarredChanges(userId);
      deleteChangeEdits(userId);
      deleteDraftCommentsUtil.deleteDraftComments(user, null);
      accountPatchReviewStore.run(a -> a.clearReviewedBy(userId));
      accountsUpdateProvider
          .get()
          .delete("Deleting user through `DELETE /accounts/{ID}`", user.getAccountId());
    } catch (Exception e) {
      throw new AccountException("Could not delete account", e);
    }
    return Response.none();
  }

  private void deletePgpKeys(IdentifiedUser user) {
    if (!publicKeyStoreUtil.hasInitializedPublicKeyStore()) {
      return;
    }
    try {
      List<RefUpdate.Result> deletedKeyResults =
          publicKeyStoreUtil.deleteAllPgpKeysForUser(
              user.getAccountId(), serverIdent.get(), serverIdent.get());
      for (RefUpdate.Result saveResult : deletedKeyResults) {
        if (saveResult != RefUpdate.Result.NO_CHANGE
            && saveResult != RefUpdate.Result.FAST_FORWARD) {
          throw new StorageException(String.format("Failed to delete PGP key: %s", saveResult));
        }
      }
    } catch (Exception e) {
      throw new StorageException("Failed to delete PGP keys.", e);
    }
  }

  private void deleteSshKeys(IdentifiedUser user) throws ConfigInvalidException, IOException {
    List<AccountSshKey> keys = authorizedKeys.getKeys(user.getAccountId());
    for (AccountSshKey key : keys) {
      authorizedKeys.deleteKey(user.getAccountId(), key.seq());
    }
    user.getUserName().ifPresent(sshKeyCache::evict);
  }

  private void deleteStarredChanges(Account.Id accountId) {
    ImmutableSet<Change.Id> staredChanges = starredChangesUtil.byAccountId(accountId, false);
    for (Change.Id change : staredChanges) {
      starredChangesUtil.unstar(self.get().getAccountId(), change);
    }
  }

  private void deleteChangeEdits(Account.Id accountId) throws IOException, QueryParseException {
    // Note: in case of a stale index, the results of this query might be incomplete.
    List<ChangeData> changesWithEdits = queryProvider.get().byOpenEditByUser(accountId);

    for (ChangeData cd : changesWithEdits) {
      for (Table.Cell<Account.Id, PatchSet.Id, Ref> edit : cd.editRefs().cellSet()) {
        if (!accountId.equals(edit.getRowKey())) {
          continue;
        }
        try (Repository repo = gitManager.openRepository(cd.project());
            RevWalk rw = new RevWalk(repo)) {
          RevCommit commit = rw.parseCommit(edit.getValue().getObjectId());
          changeEditUtil.delete(
              new ChangeEdit(
                  cd.change(),
                  edit.getValue().getName(),
                  commit,
                  cd.patchSet(edit.getColumnKey())));
        }
      }
    }
  }
}
