package com.airlock.iam.common.application.configuration.sms;

import com.airlock.iam.common.domain.model.sms.SmppBindType;
import com.airlock.iam.common.domain.model.sms.SmppDataCodingScheme;
import com.airlock.iam.common.domain.model.sms.SmppEncodingCharset;
import com.airlock.iam.common.domain.model.sms.SmppFlashMode;
import com.airlock.iam.common.domain.model.sms.SmppSmsGatewayConfiguration;
import com.airlock.iam.common.domain.service.sms.SmppSmsGateway;
import com.airlock.iam.core.domain.model.sms.SmppNpi;
import com.airlock.iam.core.domain.model.sms.SmppTon;
import com.airlock.iam.core.infrastructure.resourcepool.ResourcePool;
import com.airlock.iam.core.misc.sms.SmsGateway;
import com.airlock.iam.plugin.api.annotation.config.ConfigurationValidator;
import com.airlock.iam.plugin.api.annotation.config.Groups;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.lifecycle.AfterConfigActivation;
import com.airlock.iam.plugin.api.annotation.lifecycle.BeforePluginDeactivation;
import com.airlock.iam.plugin.api.annotation.property.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.EnumProperty;
import com.airlock.iam.plugin.api.annotation.property.FileProperty;
import com.airlock.iam.plugin.api.annotation.property.GroupProperty;
import com.airlock.iam.plugin.api.annotation.property.IntegerProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.Environment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.ConfigurationException;
import com.airlock.iam.plugin.api.exception.PropertyConstraintViolationException;
import com.airlock.iam.plugin.api.valuereader.BooleanPropertyValueReader;
import com.airlock.iam.plugin.api.valuereader.FilePropertyValueReader;
import com.airlock.iam.plugin.api.valuereader.StringPropertyValueReader;
import com.airlock.iam.plugin.framework.misc.exception.MandatoryPropertyMissingException;
import com.airlock.iam.plugin.framework.misc.processor.PasswordPropertyProcessor;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.File;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;

@Plugin(description = "SMS Gateway implementation that support sending short messages over an SMSC's SMPP v3.4 interface.", displayName = "SMPP SMS Gateway")
@Groups(groupSequence = {"Basic Settings", "Advanced Settings", "SSL Settings"}, openGroups = "Basic Settings")
public class SmppSmsGatewaySettings implements SmsGateway, ResourcePool.TrackableResourceSupplier<SmppSmsGateway> {
   static final String SSL_SETTINGS = "SSL Settings";
   private static final ResourcePool<SmppSmsGatewaySettings, SmppSmsGateway> POOL = new ResourcePool<>();
   @StringProperty(
      description = "Host address with port of the SMPP SMS Gateway.",
      optional = false,
      exampleValues = {"194.298.234.64:8080", "smpp3.infobip.com:8888", "smpp2.infobip.com:8887"}
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private String serverWithPort;
   private static final String SERVER_WITH_PORT_FIELD = "serverWithPort";
   @StringProperty(description = "Username or System ID of the registered SMPP account.", optional = false)
   @GroupProperty(groupIdentifier = "Basic Settings")
   private String accountUsername;
   @StringProperty(description = "Password of the SMPP account.", optional = false, isSensitive = true)
   @GroupProperty(groupIdentifier = "Basic Settings")
   private String accountPassword;
   @EnumProperty(
      description = "How to bind to the SMPP Gateway.<br/>SMPP supports:<br/><ul><li>Transceiver: send and receive SMS</li><li>Transmitter: send SMS</li><li>Receiver: receive SMS</li></ul>",
      optional = true,
      defaultValue = "TRANSCEIVER"
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private SmppBindType smppBindType;
   @EnumProperty(
      description = "<p>The charset to encode messages. This parameter is specified by the SMSC Server and must correlate with the \"Data Coding Scheme\" below. Notice that some charsets use more bytes than others to encode (certain) characters and thus reduce the maximum size of the message.</p>",
      optional = true,
      defaultValue = "ISO_8859_1"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private SmppEncodingCharset messageEncodingCharset;
   @EnumProperty(
      description = "<p>The DCS or Data Coding Scheme indicates to the SMSC Server how the binary message shall be interpreted. A value of 0x00 (the default) leaves the decision to the server. Unless it is configurable on the server, a more specific DCS should be chosen based on the charset above.</p>",
      optional = true,
      defaultValue = "DEFAULT"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private SmppDataCodingScheme dataCodingScheme;
   @IntegerProperty(
      description = "Maximum number of concurrent sessions to open with SMPP SMS Gateway. If this SMPP gateway is used in different modules (Adminapp, Loginapp, etc) please consider that you can not configure the maximum number of allowed sessions of your provider, as each module will get its own instance of this SMPP gateway. Keep in mind that in multi-instance setups (active-active or horizontally scaling cloud setups) with <i>n</i> instances, the number of connection pools is multiplied by <i>n</i>.",
      optional = true,
      defaultValue = 1,
      exampleValues = {1, 5},
      minValue = 1,
      maxValue = 1000
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private int maxNumberOfSessions;
   @IntegerProperty(
      description = "The window size to use.<br/>The number of unacknowledged requests is called a window; for the best performance both communicating sides must be configured with the same window size.",
      exampleValues = 1,
      optional = true,
      defaultValue = 1,
      minValue = 1,
      maxValue = Integer.MAX_VALUE
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private int windowSize;
   @IntegerProperty(
      description = "The connection timeout in milliseconds.<br/>The time how long to wait while trying to connect to the SMPP provider.<br/><br/>The send timeout in milliseconds.<br/>The time how long to wait for a response when sending an SMS.<br/>The timeout value includes both waiting for a \"window\" slot, the time it takes to transmit the actual bytes on the socket, and for the remote endpoint to send a response back.",
      exampleValues = 10000,
      optional = true,
      defaultValue = 10000,
      minValue = 1,
      maxValue = Integer.MAX_VALUE
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private int connectionAndSendTimeout;
   @EnumProperty(
      description = "The TON (type of number) value to use for the source number. If your provider doesn't need a specific one use the default value \"Unknown\" as this is supported by most of the providers.",
      optional = true,
      defaultValue = "UNKNOWN",
      displayName = "Source TON"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private SmppTon sourceTon;
   @EnumProperty(
      description = "The NPI (numbering plan identification) value to use for the source number. If your provider doesn't need a specific one use the default value \"Unknown\" as this is supported by most of the providers.",
      optional = true,
      defaultValue = "UNKNOWN",
      displayName = "Source NPI"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private SmppNpi sourceNpi;
   @EnumProperty(
      description = "The TON value to use for the destination number. If your provider doesn't need a specific one use the default value \"Unknown\" as this is supported by most of the providers.",
      optional = true,
      defaultValue = "UNKNOWN",
      displayName = "Destination TON "
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private SmppTon destTon;
   @EnumProperty(
      description = "The NPI value to use for the destination number. If your provider doesn't need a specific one use the default value \"Unknown\" as this is supported by most of the providers.",
      optional = true,
      defaultValue = "UNKNOWN",
      displayName = "Destination NPI"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private SmppNpi destNpi;
   @EnumProperty(
      description = "<p>When sending a message as flash message (Message Class 0), there are multiple ways of marking the message as such.</p><ul><li><b>DCS code 0xF0</b>: Use 0xF0 as DCS code (SMPP 3.4 default)</li><li><b>DCS code 0x10</b>: Use 0x10 as DCS code (legacy GSM mode supported by some providers)</li><li><b>dest_addr_subunit code</b>: Use the optional parameter 'dest_addr_subunit' (as suggested as the recommended way by SMPP 3.4 standard)</li><li><b>Ignore Flash</b>: In case flash doesn't work correctly or isn't able to display special characters, send flash messages as normal messages instead</li></ul>",
      optional = true,
      defaultValue = "DCS_CODE_F0"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private SmppFlashMode flashMode;
   @StringProperty(
      description = "The name of the session to the SMPP provider.<br/>If you need to give them a specific name you can do this here. Otherwise just keep the default name.",
      optional = true,
      defaultValue = "IAM-SmppSmsGateway"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private String sessionName;
   @BooleanProperty(
      description = "Enable debug logging of all communication. Please note that the logged communication may contain the account password, mobile numbers and tokens. Only enable this option while debugging connection problems.",
      optional = true,
      defaultValue = "false"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private boolean enableDebugging;
   @BooleanProperty(
      displayName = "Use SSL",
      description = "If set to true SSL will be used to communicate with the SMPP provider. If set to true make sure all other properties needed for SSL are set as well. These are the values for the key store and the trust store.",
      optional = true,
      defaultValue = "false"
   )
   @GroupProperty(groupIdentifier = "SSL Settings")
   private boolean useSsl;
   private static final String USE_SSL_FIELD = "useSsl";
   @FileProperty(
      description = "The path of the JKS trust store. Mandatory property if SSL is turned on.",
      optional = true,
      assureExistence = true,
      exampleValues = "directory/keystore.jks"
   )
   @GroupProperty(groupIdentifier = "SSL Settings")
   private File trustStorePath;
   private static final String TRUST_STORE_PATH_FIELD = "trustStorePath";
   @StringProperty(description = "The password of the JKS trust store. Mandatory property if SSL is turned on.", optional = true, isSensitive = true)
   @GroupProperty(groupIdentifier = "SSL Settings")
   private String trustStorePassword;
   private static final String TRUST_STORE_PASSWORD_FIELD = "trustStorePassword";

   @ConfigurationValidator
   public static void checkSslConfig(PluginConfiguration conf, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment) throws ConfigurationException {
      Boolean useSslConfig = BooleanPropertyValueReader.effectiveBooleanPropertyValue(conf, "useSsl", env, context);
      if (useSslConfig) {
         if (StringUtils.isEmpty(FilePropertyValueReader.effectiveFilePropertyValue(conf, "trustStorePath", env, context))) {
            throw new MandatoryPropertyMissingException("trustStorePath", conf, env, context);
         }

         if (!PasswordPropertyProcessor.isDefined(conf, "trustStorePassword", env, context)) {
            throw new MandatoryPropertyMissingException("trustStorePassword", conf, env, context);
         }
      }
   }

   @ConfigurationValidator
   public static void checkServerIpAndPort(
      PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment
   ) throws ConfigurationException {
      if (!ServerAddress.parseFrom(StringPropertyValueReader.effectiveStringConfigValue(config, "serverWithPort", env, context)).isPresent()) {
         throw new PropertyConstraintViolationException("serverWithPort", config, env, context, "Invalid syntax for server and port.");
      }
   }

   @AfterConfigActivation
   synchronized void afterConfigActivation() {
      POOL.onActivation(this);
   }

   @BeforePluginDeactivation
   public synchronized void cleanup() {
      POOL.onDeactivation(this);
   }

   public SmppSmsGateway createResource() {
      return new SmppSmsGateway(this.createSmppSmsGatewayConfiguration());
   }

   private SmppSmsGatewayConfiguration createSmppSmsGatewayConfiguration() {
      Optional<ServerAddress> serverAddress = ServerAddress.parseFrom(this.serverWithPort);
      if (serverAddress.isEmpty()) {
         throw new IllegalArgumentException("Server IP with port has not a valid syntax.");
      } else {
         return SmppSmsGatewayConfiguration.builder()
            .windowSize(this.windowSize)
            .sessionName(this.sessionName)
            .smppBindType(this.smppBindType.getValue())
            .connectionTimeout(this.connectionAndSendTimeout)
            .serverIp(serverAddress.get().getDomainName())
            .serverPort(serverAddress.get().getPort())
            .accountUsername(this.accountUsername)
            .accountPassword(this.accountPassword)
            .sourceTon(this.sourceTon.getValue())
            .destTon(this.destTon.getValue())
            .sourceNpi(this.sourceNpi.getValue())
            .destNpi(this.destNpi.getValue())
            .sendTimeout(this.connectionAndSendTimeout)
            .maxNumberOfSessions(this.maxNumberOfSessions)
            .messageEncodingCharset(this.messageEncodingCharset.getValue())
            .dataCodingScheme(this.dataCodingScheme)
            .flashMode(this.flashMode)
            .enableDebugging(this.enableDebugging)
            .useSsl(this.useSsl)
            .trustStorePath(Optional.ofNullable(this.trustStorePath == null ? null : this.trustStorePath.getAbsolutePath()))
            .trustStorePassword(Optional.ofNullable(this.trustStorePassword))
            .build();
      }
   }

   public void closeResource(SmppSmsGateway resource) {
      resource.close();
   }

   @Override
   public String sendSms(String originator, String phoneNr, String message, boolean isFlashMsg) {
      return POOL.getResource(this).sendSms(originator, phoneNr, message, isFlashMsg);
   }

   @Override
   public SmsGateway.DeliveryStatus getDeliveryStatus(String messageId) {
      return SmsGateway.DeliveryStatus.UNKNOWN;
   }

   @Override
   public boolean multiSmsMessageSupported() {
      return false;
   }

   @Override
   public boolean flashSmsMessageSupported() {
      return true;
   }

   @Override
   public boolean deliveryStatusSupported() {
      return false;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder builder() {
      return new SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public SmppSmsGatewaySettings() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public SmppSmsGatewaySettings(
      String serverWithPort,
      String accountUsername,
      String accountPassword,
      SmppBindType smppBindType,
      SmppEncodingCharset messageEncodingCharset,
      SmppDataCodingScheme dataCodingScheme,
      int maxNumberOfSessions,
      int windowSize,
      int connectionAndSendTimeout,
      SmppTon sourceTon,
      SmppNpi sourceNpi,
      SmppTon destTon,
      SmppNpi destNpi,
      SmppFlashMode flashMode,
      String sessionName,
      boolean enableDebugging,
      boolean useSsl,
      File trustStorePath,
      String trustStorePassword
   ) {
      this.serverWithPort = serverWithPort;
      this.accountUsername = accountUsername;
      this.accountPassword = accountPassword;
      this.smppBindType = smppBindType;
      this.messageEncodingCharset = messageEncodingCharset;
      this.dataCodingScheme = dataCodingScheme;
      this.maxNumberOfSessions = maxNumberOfSessions;
      this.windowSize = windowSize;
      this.connectionAndSendTimeout = connectionAndSendTimeout;
      this.sourceTon = sourceTon;
      this.sourceNpi = sourceNpi;
      this.destTon = destTon;
      this.destNpi = destNpi;
      this.flashMode = flashMode;
      this.sessionName = sessionName;
      this.enableDebugging = enableDebugging;
      this.useSsl = useSsl;
      this.trustStorePath = trustStorePath;
      this.trustStorePassword = trustStorePassword;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class SmppSmsGatewaySettingsBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String serverWithPort;
      @SuppressFBWarnings(justification = "generated code")
      private String accountUsername;
      @SuppressFBWarnings(justification = "generated code")
      private String accountPassword;
      @SuppressFBWarnings(justification = "generated code")
      private SmppBindType smppBindType;
      @SuppressFBWarnings(justification = "generated code")
      private SmppEncodingCharset messageEncodingCharset;
      @SuppressFBWarnings(justification = "generated code")
      private SmppDataCodingScheme dataCodingScheme;
      @SuppressFBWarnings(justification = "generated code")
      private int maxNumberOfSessions;
      @SuppressFBWarnings(justification = "generated code")
      private int windowSize;
      @SuppressFBWarnings(justification = "generated code")
      private int connectionAndSendTimeout;
      @SuppressFBWarnings(justification = "generated code")
      private SmppTon sourceTon;
      @SuppressFBWarnings(justification = "generated code")
      private SmppNpi sourceNpi;
      @SuppressFBWarnings(justification = "generated code")
      private SmppTon destTon;
      @SuppressFBWarnings(justification = "generated code")
      private SmppNpi destNpi;
      @SuppressFBWarnings(justification = "generated code")
      private SmppFlashMode flashMode;
      @SuppressFBWarnings(justification = "generated code")
      private String sessionName;
      @SuppressFBWarnings(justification = "generated code")
      private boolean enableDebugging;
      @SuppressFBWarnings(justification = "generated code")
      private boolean useSsl;
      @SuppressFBWarnings(justification = "generated code")
      private File trustStorePath;
      @SuppressFBWarnings(justification = "generated code")
      private String trustStorePassword;

      @SuppressFBWarnings(justification = "generated code")
      SmppSmsGatewaySettingsBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder serverWithPort(String serverWithPort) {
         this.serverWithPort = serverWithPort;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder accountUsername(String accountUsername) {
         this.accountUsername = accountUsername;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder accountPassword(String accountPassword) {
         this.accountPassword = accountPassword;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder smppBindType(SmppBindType smppBindType) {
         this.smppBindType = smppBindType;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder messageEncodingCharset(SmppEncodingCharset messageEncodingCharset) {
         this.messageEncodingCharset = messageEncodingCharset;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder dataCodingScheme(SmppDataCodingScheme dataCodingScheme) {
         this.dataCodingScheme = dataCodingScheme;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder maxNumberOfSessions(int maxNumberOfSessions) {
         this.maxNumberOfSessions = maxNumberOfSessions;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder windowSize(int windowSize) {
         this.windowSize = windowSize;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder connectionAndSendTimeout(int connectionAndSendTimeout) {
         this.connectionAndSendTimeout = connectionAndSendTimeout;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder sourceTon(SmppTon sourceTon) {
         this.sourceTon = sourceTon;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder sourceNpi(SmppNpi sourceNpi) {
         this.sourceNpi = sourceNpi;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder destTon(SmppTon destTon) {
         this.destTon = destTon;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder destNpi(SmppNpi destNpi) {
         this.destNpi = destNpi;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder flashMode(SmppFlashMode flashMode) {
         this.flashMode = flashMode;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder sessionName(String sessionName) {
         this.sessionName = sessionName;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder enableDebugging(boolean enableDebugging) {
         this.enableDebugging = enableDebugging;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder useSsl(boolean useSsl) {
         this.useSsl = useSsl;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder trustStorePath(File trustStorePath) {
         this.trustStorePath = trustStorePath;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder trustStorePassword(String trustStorePassword) {
         this.trustStorePassword = trustStorePassword;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SmppSmsGatewaySettings build() {
         return new SmppSmsGatewaySettings(
            this.serverWithPort,
            this.accountUsername,
            this.accountPassword,
            this.smppBindType,
            this.messageEncodingCharset,
            this.dataCodingScheme,
            this.maxNumberOfSessions,
            this.windowSize,
            this.connectionAndSendTimeout,
            this.sourceTon,
            this.sourceNpi,
            this.destTon,
            this.destNpi,
            this.flashMode,
            this.sessionName,
            this.enableDebugging,
            this.useSsl,
            this.trustStorePath,
            this.trustStorePassword
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "SmppSmsGatewaySettings.SmppSmsGatewaySettingsBuilder(serverWithPort="
            + this.serverWithPort
            + ", accountUsername="
            + this.accountUsername
            + ", accountPassword="
            + this.accountPassword
            + ", smppBindType="
            + this.smppBindType
            + ", messageEncodingCharset="
            + this.messageEncodingCharset
            + ", dataCodingScheme="
            + this.dataCodingScheme
            + ", maxNumberOfSessions="
            + this.maxNumberOfSessions
            + ", windowSize="
            + this.windowSize
            + ", connectionAndSendTimeout="
            + this.connectionAndSendTimeout
            + ", sourceTon="
            + this.sourceTon
            + ", sourceNpi="
            + this.sourceNpi
            + ", destTon="
            + this.destTon
            + ", destNpi="
            + this.destNpi
            + ", flashMode="
            + this.flashMode
            + ", sessionName="
            + this.sessionName
            + ", enableDebugging="
            + this.enableDebugging
            + ", useSsl="
            + this.useSsl
            + ", trustStorePath="
            + this.trustStorePath
            + ", trustStorePassword="
            + this.trustStorePassword
            + ")";
      }
   }
}
