// Copyright (C) 2009 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.account;

import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;

import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.account.externalids.ExternalIdsUpdate;
import com.google.gerrit.server.ssh.SshKeyCache;
import com.google.gwtjsonrpc.common.VoidResult;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.Callable;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Operation to change the username of an account. */
public class ChangeUserName implements Callable<VoidResult> {
  private static final Logger log = LoggerFactory.getLogger(ChangeUserName.class);

  public static final String USERNAME_CANNOT_BE_CHANGED = "Username cannot be changed.";

  /** Generic factory to change any user's username. */
  public interface Factory {
    ChangeUserName create(IdentifiedUser user, String newUsername);
  }

  private final SshKeyCache sshKeyCache;
  private final ExternalIds externalIds;
  private final ExternalIdsUpdate.Server externalIdsUpdateFactory;

  private final IdentifiedUser user;
  private final String newUsername;

  @Inject
  ChangeUserName(
      SshKeyCache sshKeyCache,
      ExternalIds externalIds,
      ExternalIdsUpdate.Server externalIdsUpdateFactory,
      @Assisted IdentifiedUser user,
      @Nullable @Assisted String newUsername) {
    this.sshKeyCache = sshKeyCache;
    this.externalIds = externalIds;
    this.externalIdsUpdateFactory = externalIdsUpdateFactory;
    this.user = user;
    this.newUsername = newUsername;
  }

  @Override
  public VoidResult call()
      throws OrmException, NameAlreadyUsedException, InvalidUserNameException, IOException,
          ConfigInvalidException {
    Collection<ExternalId> old = externalIds.byAccount(user.getAccountId(), SCHEME_USERNAME);
    if (!old.isEmpty()) {
      log.error(
          "External id with scheme \"username:\" already exists for the user {}",
          user.getAccountId());
      throw new IllegalStateException(USERNAME_CANNOT_BE_CHANGED);
    }

    ExternalIdsUpdate externalIdsUpdate = externalIdsUpdateFactory.create();
    if (newUsername != null && !newUsername.isEmpty()) {
      if (!ExternalId.isValidUsername(newUsername)) {
        throw new InvalidUserNameException();
      }

      ExternalId.Key key = ExternalId.Key.create(SCHEME_USERNAME, newUsername);
      try {
        String password = null;
        for (ExternalId i : old) {
          if (i.password() != null) {
            password = i.password();
          }
        }
        externalIdsUpdate.insert(ExternalId.create(key, user.getAccountId(), null, password));
        log.info("Created the new external Id with key: {}", key);
      } catch (OrmDuplicateKeyException dupeErr) {
        // If we are using this identity, don't report the exception.
        //
        ExternalId other = externalIds.get(key);
        if (other != null && other.accountId().equals(user.getAccountId())) {
          return VoidResult.INSTANCE;
        }

        // Otherwise, someone else has this identity.
        //
        throw new NameAlreadyUsedException(newUsername);
      }
    }

    // If we have any older user names, remove them.
    //
    externalIdsUpdate.delete(old);
    for (ExternalId extId : old) {
      sshKeyCache.evict(extId.key().id());
    }

    sshKeyCache.evict(newUsername);
    return VoidResult.INSTANCE;
  }
}
