// Copyright (C) 2015 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.auth.oauth;

import com.google.common.base.Strings;
import com.google.gerrit.extensions.auth.oauth.OAuthLoginProvider;
import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo;
import com.google.gerrit.extensions.client.AccountFieldName;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.AbstractRealm;
import com.google.gerrit.server.account.AccountException;
import com.google.gerrit.server.account.AccountManager;
import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.eclipse.jgit.lib.Config;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

@Singleton
public class OAuthRealm extends AbstractRealm {
  private final DynamicMap<OAuthLoginProvider> loginProviders;
  private final Set<AccountFieldName> editableAccountFields;

  @Inject
  OAuthRealm(DynamicMap<OAuthLoginProvider> loginProviders,
      @GerritServerConfig Config config) {
    this.loginProviders = loginProviders;
    this.editableAccountFields = new HashSet<>();
    if (config.getBoolean("oauth", null, "allowEditFullName", false)) {
      editableAccountFields.add(AccountFieldName.FULL_NAME);
    }
    if (config.getBoolean("oauth", null, "allowRegisterNewEmail", false)) {
      editableAccountFields.add(AccountFieldName.REGISTER_NEW_EMAIL);
    }
  }

  @Override
  public boolean allowsEdit(AccountFieldName field) {
    return editableAccountFields.contains(field);
  }

  /**
   * Authenticates with the {@link OAuthLoginProvider} specified
   * in the authentication request.
   *
   * {@link AccountManager} calls this method without password
   * if authenticity of the user has already been established.
   * In that case the {@link AuthRequest} is supposed to contain
   * a resolved email address and we can skip the authentication
   * request to the {@code OAuthLoginService}.
   *
   * @param who the authentication request.
   *
   * @return the authentication request with resolved email address
   * and display name in case the authenticity of the user could
   * be established; otherwise {@code who} is returned unchanged.
   *
   * @throws AccountException if the authentication request with
   * the OAuth2 server failed or no {@code OAuthLoginProvider} was
   * available to handle the request.
   */
  @Override
  public AuthRequest authenticate(AuthRequest who) throws AccountException {
    if (Strings.isNullOrEmpty(who.getPassword()) &&
        !Strings.isNullOrEmpty(who.getEmailAddress())) {
      return who;
    }

    if (Strings.isNullOrEmpty(who.getAuthPlugin())
        || Strings.isNullOrEmpty(who.getAuthProvider())) {
      throw new AccountException("Cannot authenticate");
    }
    OAuthLoginProvider loginProvider =
        loginProviders.get(who.getAuthPlugin(), who.getAuthProvider());
    if (loginProvider == null) {
      throw new AccountException("Cannot authenticate");
    }

    OAuthUserInfo userInfo;
    try {
      userInfo = loginProvider.login(who.getUserName(), who.getPassword());
    } catch (IOException e) {
      throw new AccountException("Cannot authenticate", e);
    }
    if (userInfo == null) {
      throw new AccountException("Cannot authenticate");
    }
    if (!Strings.isNullOrEmpty(userInfo.getEmailAddress())
        && (Strings.isNullOrEmpty(who.getUserName())
            || !allowsEdit(AccountFieldName.REGISTER_NEW_EMAIL))) {
      who.setEmailAddress(userInfo.getEmailAddress());
    }
    if (!Strings.isNullOrEmpty(userInfo.getDisplayName())
        && (Strings.isNullOrEmpty(who.getDisplayName())
            || !allowsEdit(AccountFieldName.FULL_NAME))) {
      who.setDisplayName(userInfo.getDisplayName());
    }
    return who;
  }

  @Override
  public void onCreateAccount(AuthRequest who, Account account) {
  }

  @Override
  public Account.Id lookup(String accountName) {
    return null;
  }
}
