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

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;

import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.common.Input;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
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.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.ServerInitiated;
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jgit.errors.ConfigInvalidException;

/**
 * REST endpoint to set an email address as preferred email address for an account.
 *
 * <p>This REST endpoint handles {@code PUT
 * /accounts/<account-identifier>/emails/<email-identifier>/preferred} requests.
 *
 * <p>Users can only set an email address as preferred that is assigned to their account as external
 * ID.
 */
@Singleton
public class PutPreferred implements RestModifyView<AccountResource.Email, Input> {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final Provider<CurrentUser> self;
  private final PermissionBackend permissionBackend;
  private final Provider<AccountsUpdate> accountsUpdateProvider;
  private final ExternalIds externalIds;

  @Inject
  PutPreferred(
      Provider<CurrentUser> self,
      PermissionBackend permissionBackend,
      @ServerInitiated Provider<AccountsUpdate> accountsUpdateProvider,
      ExternalIds externalIds) {
    this.self = self;
    this.permissionBackend = permissionBackend;
    this.accountsUpdateProvider = accountsUpdateProvider;
    this.externalIds = externalIds;
  }

  @Override
  public Response<String> apply(AccountResource.Email rsrc, Input input)
      throws RestApiException, IOException, PermissionBackendException, ConfigInvalidException {
    if (!self.get().hasSameAccountId(rsrc.getUser())) {
      permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
    }
    return apply(rsrc.getUser(), rsrc.getEmail());
  }

  public Response<String> apply(IdentifiedUser user, String preferredEmail)
      throws RestApiException, IOException, ConfigInvalidException {
    AtomicReference<Optional<RestApiException>> exception = new AtomicReference<>(Optional.empty());
    AtomicBoolean alreadyPreferred = new AtomicBoolean(false);
    accountsUpdateProvider
        .get()
        .update(
            "Set Preferred Email via API",
            user.getAccountId(),
            (a, u) -> {
              if (preferredEmail.equals(a.account().preferredEmail())) {
                alreadyPreferred.set(true);
              } else {
                // check if the user has a matching email
                String matchingEmail = null;
                for (String email :
                    a.externalIds().stream()
                        .map(ExternalId::email)
                        .filter(Objects::nonNull)
                        .collect(toSet())) {
                  if (email.equals(preferredEmail)) {
                    // we have an email that matches exactly, prefer this one
                    matchingEmail = email;
                    break;
                  } else if (matchingEmail == null && email.equalsIgnoreCase(preferredEmail)) {
                    // we found an email that matches but has a different case
                    matchingEmail = email;
                  }
                }

                if (matchingEmail == null) {
                  // user doesn't have an external ID for this email
                  if (user.hasEmailAddress(preferredEmail)) {
                    // but Realm says the user is allowed to use this email
                    Set<ExternalId> existingExtIdsWithThisEmail =
                        externalIds.byEmail(preferredEmail);
                    if (!existingExtIdsWithThisEmail.isEmpty()) {
                      // but the email is already assigned to another account
                      logger.atWarning().log(
                          "Cannot set preferred email %s for account %s because it is owned"
                              + " by the following account(s): %s",
                          preferredEmail,
                          user.getAccountId(),
                          existingExtIdsWithThisEmail.stream()
                              .map(ExternalId::accountId)
                              .collect(toList()));
                      exception.set(
                          Optional.of(
                              new ResourceConflictException("email in use by another account")));
                      return;
                    }

                    // claim the email now
                    u.addExternalId(ExternalId.createEmail(a.account().id(), preferredEmail));
                    matchingEmail = preferredEmail;
                  } else {
                    // Realm says that the email doesn't belong to the user. This can only happen as
                    // a race condition because EmailsCollection would have thrown
                    // ResourceNotFoundException already before invoking this REST endpoint.
                    exception.set(Optional.of(new ResourceNotFoundException(preferredEmail)));
                    return;
                  }
                }
                u.setPreferredEmail(matchingEmail);
              }
            })
        .orElseThrow(() -> new ResourceNotFoundException("account not found"));
    if (exception.get().isPresent()) {
      throw exception.get().get();
    }
    return alreadyPreferred.get() ? Response.ok() : Response.created();
  }
}
