// 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.googlesource.gerrit.plugins.oauth;

import static java.util.Objects.requireNonNull;

import com.google.common.base.Strings;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitStep;
import com.google.gerrit.pgm.init.api.Section;
import com.google.inject.Inject;
import com.google.inject.ProvisionException;
import java.net.URI;

class InitOAuth implements InitStep {
  static final String PLUGIN_SECTION = "plugin";
  static final String CLIENT_ID = "client-id";
  static final String CLIENT_SECRET = "client-secret";
  static final String LINK_TO_EXISTING_OPENID_ACCOUNT = "link-to-existing-openid-accounts";
  static final String FIX_LEGACY_USER_ID = "fix-legacy-user-id";
  static final String DOMAIN = "domain";
  static final String USE_EMAIL_AS_USERNAME = "use-email-as-username";
  static final String USE_PREFERRED_USERNAME = "use-preferred-username";
  static final String ROOT_URL = "root-url";
  static final String REALM = "realm";
  static final String TENANT = "tenant";
  static final String LINK_TO_EXISTING_OFFICE365_ACCOUNT = "link-to-existing-office365-accounts";
  static final String SERVICE_NAME = "service-name";
  static String FIX_LEGACY_USER_ID_QUESTION = "Fix legacy user id, without oauth provider prefix?";

  private final ConsoleUI ui;
  private final Section googleOAuthProviderSection;
  private final Section githubOAuthProviderSection;
  private final Section bitbucketOAuthProviderSection;
  private final Section casOAuthProviderSection;
  private final Section facebookOAuthProviderSection;
  private final Section gitlabOAuthProviderSection;
  private final Section lemonldapOAuthProviderSection;
  private final Section dexOAuthProviderSection;
  private final Section keycloakOAuthProviderSection;
  private final Section office365OAuthProviderSection;
  private final Section azureActiveDirectoryAuthProviderSection;
  private final Section airVantageOAuthProviderSection;
  private final Section phabricatorOAuthProviderSection;
  private final Section tuleapOAuthProviderSection;

  @Inject
  InitOAuth(ConsoleUI ui, Section.Factory sections, @PluginName String pluginName) {
    this.ui = ui;
    this.googleOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + GoogleOAuthService.CONFIG_SUFFIX);
    this.githubOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + GitHubOAuthService.CONFIG_SUFFIX);
    this.bitbucketOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + BitbucketOAuthService.CONFIG_SUFFIX);
    this.casOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + CasOAuthService.CONFIG_SUFFIX);
    this.facebookOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + FacebookOAuthService.CONFIG_SUFFIX);
    this.gitlabOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + GitLabOAuthService.CONFIG_SUFFIX);
    this.lemonldapOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + LemonLDAPOAuthService.CONFIG_SUFFIX);
    this.dexOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + DexOAuthService.CONFIG_SUFFIX);
    this.keycloakOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + KeycloakOAuthService.CONFIG_SUFFIX);
    this.office365OAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX_LEGACY);
    this.azureActiveDirectoryAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX);
    this.airVantageOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + AirVantageOAuthService.CONFIG_SUFFIX);
    this.phabricatorOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + PhabricatorOAuthService.CONFIG_SUFFIX);
    this.tuleapOAuthProviderSection =
        sections.get(PLUGIN_SECTION, pluginName + TuleapOAuthService.CONFIG_SUFFIX);
  }

  @Override
  public void run() throws Exception {
    ui.header("OAuth Authentication Provider");

    boolean configureGoogleOAuthProvider =
        ui.yesno(
            isConfigured(googleOAuthProviderSection),
            "Use Google OAuth provider for Gerrit login ?");
    if (configureGoogleOAuthProvider && configureOAuth(googleOAuthProviderSection)) {
      googleOAuthProviderSection.string(FIX_LEGACY_USER_ID_QUESTION, FIX_LEGACY_USER_ID, "false");
    }

    boolean configueGitHubOAuthProvider =
        ui.yesno(
            isConfigured(githubOAuthProviderSection),
            "Use GitHub OAuth provider for Gerrit login ?");
    if (configueGitHubOAuthProvider && configureOAuth(githubOAuthProviderSection)) {
      githubOAuthProviderSection.string(FIX_LEGACY_USER_ID_QUESTION, FIX_LEGACY_USER_ID, "false");
    }

    boolean configureBitbucketOAuthProvider =
        ui.yesno(
            isConfigured(bitbucketOAuthProviderSection),
            "Use Bitbucket OAuth provider for Gerrit login ?");
    if (configureBitbucketOAuthProvider && configureOAuth(bitbucketOAuthProviderSection)) {
      bitbucketOAuthProviderSection.string(
          FIX_LEGACY_USER_ID_QUESTION, FIX_LEGACY_USER_ID, "false");
    }

    boolean configureCasOAuthProvider =
        ui.yesno(
            isConfigured(casOAuthProviderSection), "Use CAS OAuth provider for Gerrit login ?");
    if (configureCasOAuthProvider && configureOAuth(casOAuthProviderSection)) {
      checkRootUrl(casOAuthProviderSection.string("CAS Root URL", ROOT_URL, null));
      casOAuthProviderSection.string(FIX_LEGACY_USER_ID_QUESTION, FIX_LEGACY_USER_ID, "false");
    }

    boolean configueFacebookOAuthProvider =
        ui.yesno(
            isConfigured(facebookOAuthProviderSection),
            "Use Facebook OAuth provider for Gerrit login ?");
    if (configueFacebookOAuthProvider) {
      configureOAuth(facebookOAuthProviderSection);
    }

    boolean configureGitLabOAuthProvider =
        ui.yesno(
            isConfigured(gitlabOAuthProviderSection),
            "Use GitLab OAuth provider for Gerrit login ?");
    if (configureGitLabOAuthProvider && configureOAuth(gitlabOAuthProviderSection)) {
      checkRootUrl(gitlabOAuthProviderSection.string("GitLab Root URL", ROOT_URL, null));
    }

    boolean configureLemonLDAPOAuthProvider =
        ui.yesno(
            isConfigured(lemonldapOAuthProviderSection),
            "Use LemonLDAP OAuth provider for Gerrit login ?");
    if (configureLemonLDAPOAuthProvider) {
      checkRootUrl(lemonldapOAuthProviderSection.string("LemonLDAP Root URL", ROOT_URL, null));
      configureOAuth(lemonldapOAuthProviderSection);
    }

    boolean configureDexOAuthProvider =
        ui.yesno(
            isConfigured(dexOAuthProviderSection), "Use Dex OAuth provider for Gerrit login ?");
    if (configureDexOAuthProvider && configureOAuth(dexOAuthProviderSection)) {
      checkRootUrl(dexOAuthProviderSection.string("Dex Root URL", ROOT_URL, null));
    }

    boolean configureKeycloakOAuthProvider =
        ui.yesno(
            isConfigured(keycloakOAuthProviderSection),
            "Use Keycloak OAuth provider for Gerrit login ?");
    if (configureKeycloakOAuthProvider && configureOAuth(keycloakOAuthProviderSection)) {
      checkRootUrl(keycloakOAuthProviderSection.string("Keycloak Root URL", ROOT_URL, null));
      keycloakOAuthProviderSection.string("Keycloak Realm", REALM, null);
    }

    // ?: Are there legacy office365 already configured on the system?
    if (isConfigured(office365OAuthProviderSection)) {
      // -> Yes, this system has already configured the old legacy office365.
      boolean configureOffice365OAuthProvider =
          ui.yesno(
              isConfigured(office365OAuthProviderSection),
              "Use Office365 OAuth provider for Gerrit login ?");
      if (configureOffice365OAuthProvider) {
        configureOAuth(office365OAuthProviderSection);
      }
    }
    // E-> No, we either are setting up on an new system or using the new azure config
    else {
      boolean configureAzureActiveDirectoryAuthProvider =
          ui.yesno(
              isConfigured(azureActiveDirectoryAuthProviderSection),
              "Use Azure OAuth provider for Gerrit login ?");
      if (configureAzureActiveDirectoryAuthProvider) {
        configureOAuth(azureActiveDirectoryAuthProviderSection);
        azureActiveDirectoryAuthProviderSection.string(
            "Tenant", TENANT, AzureActiveDirectoryService.DEFAULT_TENANT);
      }
    }

    boolean configureAirVantageOAuthProvider =
        ui.yesno(
            isConfigured(airVantageOAuthProviderSection),
            "Use AirVantage OAuth provider for Gerrit login ?");
    if (configureAirVantageOAuthProvider) {
      configureOAuth(airVantageOAuthProviderSection);
    }

    boolean configurePhabricatorOAuthProvider =
        ui.yesno(
            isConfigured(phabricatorOAuthProviderSection),
            "Use Phabricator OAuth provider for Gerrit login ?");
    if (configurePhabricatorOAuthProvider && configureOAuth(phabricatorOAuthProviderSection)) {
      checkRootUrl(phabricatorOAuthProviderSection.string("Phabricator Root URL", ROOT_URL, null));
    }

    boolean configureTuleapOAuthProvider =
        ui.yesno(
            isConfigured(tuleapOAuthProviderSection),
            "Use Tuleap OAuth provider for Gerrit login ?");
    if (configureTuleapOAuthProvider && configureOAuth(tuleapOAuthProviderSection)) {
      checkRootUrl(tuleapOAuthProviderSection.string("Tuleap Root URL", ROOT_URL, null));
    }
  }

  /**
   * Retrieve client id to check whether or not this provider was already configured.
   *
   * @param s OAuth provider section
   * @return true if client id key is present, false otherwise
   */
  private static boolean isConfigured(Section s) {
    return !Strings.isNullOrEmpty(s.get(CLIENT_ID));
  }

  /**
   * Configure OAuth provider section
   *
   * @param s section to configure
   * @return true if section is present, false otherwise
   */
  private static boolean configureOAuth(Section s) {
    if (!Strings.isNullOrEmpty(s.string("Application client id", CLIENT_ID, null))) {
      s.passwordForKey("Application client secret", CLIENT_SECRET);
      return true;
    }
    return false;
  }

  /**
   * Check root URL parameter. It must be not null and it must be an absolute URI.
   *
   * @param rootUrl root URL
   * @throws ProvisionException if rootUrl wasn't provided or is not absolute URI.
   */
  private static void checkRootUrl(String rootUrl) {
    requireNonNull(rootUrl);
    if (!URI.create(rootUrl).isAbsolute()) {
      throw new ProvisionException("Root URL must be absolute URL");
    }
  }

  @Override
  public void postRun() throws Exception {}
}
