/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal.cli.commands;

import static org.apache.geode.distributed.ConfigurationProperties.CLUSTER_SSL_KEYSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_KEYSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_KEYSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_PASSWORD;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.File;
import java.util.Properties;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

import org.apache.geode.management.cli.Result;
import org.apache.geode.management.internal.cli.i18n.CliStrings;
import org.apache.geode.management.internal.cli.result.CommandResult;
import org.apache.geode.management.internal.cli.result.model.ResultModel;
import org.apache.geode.management.internal.cli.shell.Gfsh;
import org.apache.geode.management.internal.cli.shell.OperationInvoker;
import org.apache.geode.test.junit.rules.GfshParserRule;

public class ConnectCommandTest {

  @ClassRule
  public static GfshParserRule gfshParserRule = new GfshParserRule();

  private ConnectCommand connectCommand;
  private Gfsh gfsh;
  private CommandResult result;
  private ResultModel resultModel;
  private OperationInvoker operationInvoker;
  private Properties properties;
  private ArgumentCaptor<File> fileCaptor;

  @Before
  public void before() throws Exception {
    properties = new Properties();
    gfsh = mock(Gfsh.class);
    operationInvoker = mock(OperationInvoker.class);
    when(gfsh.getOperationInvoker()).thenReturn(operationInvoker);
    // using spy instead of mock because we want to call the real method when we do connect
    connectCommand = spy(ConnectCommand.class);
    when(connectCommand.getGfsh()).thenReturn(gfsh);
    doReturn(properties).when(connectCommand).loadProperties(any());
    result = mock(CommandResult.class);
    resultModel = mock(ResultModel.class);
    when(connectCommand.httpConnect(any(), any(), anyBoolean())).thenReturn(resultModel);
    when(connectCommand.jmxConnect(any(), anyBoolean(), any(), any(), anyBoolean()))
        .thenReturn(resultModel);
    fileCaptor = ArgumentCaptor.forClass(File.class);
  }

  @Test
  public void whenGfshIsAlreadyConnected() throws Exception {
    when(gfsh.isConnectedAndReady()).thenReturn(true);
    gfshParserRule.executeAndAssertThat(connectCommand, "connect")
        .containsOutput("Already connected to");
  }

  @Test
  public void promptForPasswordIfUsernameIsGiven() throws Exception {
    doReturn(properties).when(connectCommand).resolveSslProperties(any(), anyBoolean(), any(),
        any());
    result = gfshParserRule.executeCommandWithInstance(connectCommand, "connect --user=user");
    verify(gfsh).readPassword(CliStrings.CONNECT__PASSWORD + ": ");

    assertThat(properties.getProperty("security-username")).isEqualTo("user");
    assertThat(properties.getProperty("security-password")).isEqualTo("");
  }

  @Test
  public void notPromptForPasswordIfUsernameIsGiven() throws Exception {
    doReturn(properties).when(connectCommand).resolveSslProperties(any(), anyBoolean(), any(),
        any());
    result = gfshParserRule.executeCommandWithInstance(connectCommand,
        "connect --user=user --password=pass");
    verify(gfsh, times(0)).readPassword(CliStrings.CONNECT__PASSWORD + ": ");

    assertThat(properties.getProperty("security-username")).isEqualTo("user");
    assertThat(properties.getProperty("security-password")).isEqualTo("pass");
  }

  @Test
  public void notPromptForPasswordIfuserNameIsGivenInFile() throws Exception {
    // username specified in property file won't prompt for password
    properties.setProperty("security-username", "user");
    doReturn(properties).when(connectCommand).loadProperties(any(File.class));

    result = gfshParserRule.executeCommandWithInstance(connectCommand, "connect");
    verify(gfsh, times(0)).readPassword(CliStrings.CONNECT__PASSWORD + ": ");

    assertThat(properties).doesNotContainKey("security-password");
  }

  @Test
  public void plainConnectNotLoadFileNotPrompt() throws Exception {
    result = gfshParserRule.executeCommandWithInstance(connectCommand, "connect");
    // will not try to load from any file
    verify(connectCommand).loadProperties(null, null);

    // will not try to prompt
    verify(gfsh, times(0)).readText(any());
    verify(gfsh, times(0)).readPassword(any());
  }

  @Test
  public void connectUseSsl() throws Exception {
    result = gfshParserRule.executeCommandWithInstance(connectCommand, "connect --use-ssl");

    // will not try to load from any file
    verify(connectCommand).loadProperties(null, null);

    // gfsh will prompt for the all the ssl properties
    verify(gfsh).readText("key-store: ");
    verify(gfsh).readPassword("key-store-password: ");
    verify(gfsh).readText("key-store-type(default: JKS): ");
    verify(gfsh).readText("trust-store: ");
    verify(gfsh).readPassword("trust-store-password: ");
    verify(gfsh).readText("trust-store-type(default: JKS): ");
    verify(gfsh).readText("ssl-ciphers(default: any): ");
    verify(gfsh).readText("ssl-protocols(default: any): ");

    // verify the resulting properties has correct values
    assertThat(properties).hasSize(9);
    assertThat(properties.getProperty("ssl-keystore")).isEqualTo("");
    assertThat(properties.getProperty("ssl-keystore-password")).isEqualTo("");
    assertThat(properties.getProperty("ssl-keystore-type")).isEqualTo("JKS");
    assertThat(properties.getProperty("ssl-truststore")).isEqualTo("");
    assertThat(properties.getProperty("ssl-truststore-password")).isEqualTo("");
    assertThat(properties.getProperty("ssl-truststore-type")).isEqualTo("JKS");
    assertThat(properties.getProperty("ssl-ciphers")).isEqualTo("any");
    assertThat(properties.getProperty("ssl-protocols")).isEqualTo("any");
    assertThat(properties.getProperty("ssl-enabled-components")).isEqualTo("all");
  }

  @Test
  public void securityFileContainsSSLPropsAndNoUseSSL() throws Exception {
    properties.setProperty(SSL_KEYSTORE, "keystore");
    result = gfshParserRule.executeCommandWithInstance(connectCommand,
        "connect --security-properties-file=test");

    // will try to load from this file
    verify(connectCommand).loadProperties(any(), fileCaptor.capture());
    assertThat(fileCaptor.getValue()).hasName("test");

    // it will prompt for missing properties
    verify(gfsh, times(6)).readText(any());
    verify(gfsh, times(2)).readPassword(any());
  }

  @Test
  public void securityFileContainsNoSSLPropsAndNoUseSSL() throws Exception {
    result = gfshParserRule.executeCommandWithInstance(connectCommand,
        "connect --security-properties-file=test");

    // will try to load from this file
    verify(connectCommand).loadProperties(any(), fileCaptor.capture());
    assertThat(fileCaptor.getValue()).hasName("test");

    // it will prompt for missing properties
    verify(gfsh, times(0)).readText(any());
    verify(gfsh, times(0)).readPassword(any());
  }

  @Test
  public void connectUseLegacySecurityPropertiesFile() throws Exception {
    properties.setProperty(JMX_MANAGER_SSL_KEYSTORE, "jmx-keystore");
    result = gfshParserRule.executeCommandWithInstance(connectCommand,
        "connect --security-properties-file=test --key-store=keystore --key-store-password=password");

    // wil try to load from this file
    verify(connectCommand).loadProperties(fileCaptor.capture());
    assertThat(fileCaptor.getValue()).hasName("test");

    // it will not prompt for missing properties
    verify(gfsh, times(0)).readText(any());
    verify(gfsh, times(0)).readPassword(any());

    // the command option will be ignored
    assertThat(properties).hasSize(1);
    assertThat(properties.get(JMX_MANAGER_SSL_KEYSTORE)).isEqualTo("jmx-keystore");
  }

  @Test
  public void connectUseSecurityPropertiesFile_promptForMissing() throws Exception {
    properties.setProperty(SSL_KEYSTORE, "keystore");
    properties.setProperty(SSL_KEYSTORE_PASSWORD, "password");
    result = gfshParserRule.executeCommandWithInstance(connectCommand,
        "connect --security-properties-file=test");

    // since nothing is loaded, will prompt for all missing values
    verify(gfsh, times(6)).readText(any());
    verify(gfsh, times(1)).readPassword(any());
  }

  @Test
  public void connectUseSecurityPropertiesFileAndOption_promptForMissing() throws Exception {
    properties.setProperty(SSL_KEYSTORE, "keystore");
    properties.setProperty(SSL_KEYSTORE_PASSWORD, "password");
    result = gfshParserRule.executeCommandWithInstance(connectCommand,
        "connect --security-properties-file=test --key-store=keystore2 --trust-store=truststore2");

    // since nothing is loaded, will prompt for all missing values
    verify(gfsh, times(5)).readText(any());
    verify(gfsh, times(1)).readPassword(any());

    assertThat(properties).hasSize(9);
    assertThat(properties.getProperty("ssl-keystore")).isEqualTo("keystore2");
    assertThat(properties.getProperty("ssl-keystore-password")).isEqualTo("password");
    assertThat(properties.getProperty("ssl-keystore-type")).isEqualTo("JKS");
    assertThat(properties.getProperty("ssl-truststore")).isEqualTo("truststore2");
    assertThat(properties.getProperty("ssl-truststore-password")).isEqualTo("");
    assertThat(properties.getProperty("ssl-truststore-type")).isEqualTo("JKS");
    assertThat(properties.getProperty("ssl-ciphers")).isEqualTo("any");
    assertThat(properties.getProperty("ssl-protocols")).isEqualTo("any");
    assertThat(properties.getProperty("ssl-enabled-components")).isEqualTo("all");
  }

  @Test
  public void containsLegacySSLConfigTest_ssl() throws Exception {
    properties.setProperty(SSL_KEYSTORE, "keystore");
    assertThat(ConnectCommand.containsLegacySSLConfig(properties)).isFalse();
  }

  @Test
  public void containsLegacySSLConfigTest_cluster() throws Exception {
    properties.setProperty(CLUSTER_SSL_KEYSTORE, "cluster-keystore");
    assertThat(ConnectCommand.containsLegacySSLConfig(properties)).isTrue();
  }

  @Test
  public void containsLegacySSLConfigTest_jmx() throws Exception {
    properties.setProperty(JMX_MANAGER_SSL_KEYSTORE, "jmx-keystore");
    assertThat(ConnectCommand.containsLegacySSLConfig(properties)).isTrue();
  }

  @Test
  public void containsLegacySSLConfigTest_http() throws Exception {
    properties.setProperty(HTTP_SERVICE_SSL_KEYSTORE, "http-keystore");
    assertThat(ConnectCommand.containsLegacySSLConfig(properties)).isTrue();
  }

  @Test
  public void loadPropertiesWithNull() throws Exception {
    doCallRealMethod().when(connectCommand).loadProperties(any());
    assertThat(connectCommand.loadProperties(null, null)).isEmpty();
  }

  @Test
  public void isSslImpliedByOptions() throws Exception {
    assertThat(connectCommand.isSslImpliedBySslOptions((String) null)).isFalse();
    assertThat(connectCommand.isSslImpliedBySslOptions((String[]) null)).isFalse();

    assertThat(connectCommand.isSslImpliedBySslOptions(null, null, null)).isFalse();

    assertThat(connectCommand.isSslImpliedBySslOptions(null, "test")).isTrue();
  }

  @Test
  public void resolveSslProperties() throws Exception {
    // assume properties loaded from either file has an ssl property
    properties.setProperty(SSL_KEYSTORE, "keystore");
    properties = connectCommand.resolveSslProperties(gfsh, false, null, null);
    assertThat(properties).hasSize(9);

    properties.clear();

    properties.setProperty(SSL_KEYSTORE, "keystore");
    properties =
        connectCommand.resolveSslProperties(gfsh, false, null, null, "keystore2", "password");
    assertThat(properties).hasSize(9);
    assertThat(properties.getProperty(SSL_KEYSTORE)).isEqualTo("keystore2");
    assertThat(properties.getProperty(SSL_KEYSTORE_PASSWORD)).isEqualTo("password");
  }

  @Test
  public void connectToManagerWithDifferentMajorVersion() {
    when(gfsh.getVersion()).thenReturn("2.2");
    when(operationInvoker.getRemoteVersion()).thenReturn("1.2");
    when(operationInvoker.isConnected()).thenReturn(true);
    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
        .statusIsError()
        .containsOutput("Cannot use a 2.2 gfsh client to connect to a 1.2 cluster.");
  }

  @Test
  public void connectToManagerWithDifferentMinorVersion() {
    when(gfsh.getVersion()).thenReturn("1.2");
    when(operationInvoker.getRemoteVersion()).thenReturn("1.3");
    when(operationInvoker.isConnected()).thenReturn(true);
    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
        .statusIsError()
        .containsOutput("Cannot use a 1.2 gfsh client to connect to a 1.3 cluster.");
  }

  @Test
  public void connectToManagerWithGreaterPatchVersion() {
    when(gfsh.getGeodeSerializationVersion()).thenReturn("1.5.1");
    when(operationInvoker.getRemoteGeodeSerializationVersion()).thenReturn("1.5.2");
    when(operationInvoker.isConnected()).thenReturn(true);
    when(resultModel.getStatus()).thenReturn(Result.Status.OK);

    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
        .statusIsSuccess();
  }

  @Test
  public void connectToManagerWithNoPatchVersion() {
    when(gfsh.getGeodeSerializationVersion()).thenReturn("1.5.1");
    when(operationInvoker.getRemoteGeodeSerializationVersion()).thenReturn("1.5");
    when(operationInvoker.isConnected()).thenReturn(true);
    when(resultModel.getStatus()).thenReturn(Result.Status.OK);

    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
        .statusIsSuccess();
  }

  @Test
  public void connectToManagerWithLessorPatchVersion() {
    when(gfsh.getGeodeSerializationVersion()).thenReturn("1.5.1");
    when(operationInvoker.getRemoteGeodeSerializationVersion()).thenReturn("1.5.0");
    when(operationInvoker.isConnected()).thenReturn(true);
    when(resultModel.getStatus()).thenReturn(Result.Status.OK);

    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
        .statusIsSuccess();
  }

  @Test
  public void connectToOlderManagerWithNewerGfsh() {
    when(gfsh.getVersion()).thenReturn("1.5");
    when(operationInvoker.getRemoteVersion())
        .thenThrow(new RuntimeException("release version not available"));
    when(operationInvoker.isConnected()).thenReturn(true);

    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
        .statusIsError().containsOutput("Cannot use a 1.5 gfsh client to connect to this cluster.");
  }

  @Test
  public void connectToAValidManager() {
    when(gfsh.getGeodeSerializationVersion()).thenReturn("1.5");
    when(operationInvoker.getRemoteGeodeSerializationVersion()).thenReturn("1.5");
    when(operationInvoker.isConnected()).thenReturn(true);

    when(resultModel.getStatus()).thenReturn(Result.Status.OK);
    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
        .statusIsSuccess();
  }
}
