package com.airlock.iam.servicecontainer.app.infrastructure.event.azure;

import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.InitializeException;
import com.airlock.iam.plugin.api.exception.PropertyConfigurationException;
import com.airlock.iam.plugin.api.exception.PropertyConstraintViolationException;
import com.airlock.iam.plugin.api.exception.PropertyTypeMismatchException;
import com.airlock.iam.plugin.api.testlet.Testlet;
import com.airlock.iam.plugin.api.testlet.Testlet.TestletResult;
import com.airlock.iam.plugin.api.testlet.Testlet.TestletType;
import com.airlock.iam.plugin.api.testlet.Testlet.TestletResult.TestResult;
import com.airlock.iam.plugin.api.valuereader.EnumPropertyValueReader;
import com.airlock.iam.plugin.api.valuereader.FilePropertyValueReader;
import com.airlock.iam.plugin.api.valuereader.IntegerPropertyValueReader;
import com.airlock.iam.plugin.api.valuereader.PasswordPropertyValueReader;
import com.airlock.iam.plugin.api.valuereader.PluginPropertyValueReader;
import com.airlock.iam.plugin.api.valuereader.StringPropertyValueReader;
import com.airlock.iam.servicecontainer.app.application.configuration.event.azure.AmqpTransportType;
import com.airlock.iam.servicecontainer.app.application.configuration.event.azure.AzureAuthenticationSettings;
import com.airlock.iam.servicecontainer.app.application.configuration.event.azure.AzureCertificateAuthenticationConfig;
import com.airlock.iam.servicecontainer.app.application.configuration.event.azure.AzureClientSecretAuthenticationConfig;
import com.airlock.iam.servicecontainer.app.application.configuration.event.azure.AzureDefaultAuthenticationConfig;
import com.airlock.iam.servicecontainer.app.application.configuration.event.azure.AzureMessageBrokerConnectorSettings;
import com.airlock.iam.servicecontainer.app.application.configuration.event.azure.AzureProxySettings;
import com.airlock.iam.servicecontainer.app.application.configuration.event.azure.ProxyAuthenticationType;
import com.airlock.iam.servicecontainer.app.domain.service.event.EventHubClient;
import com.google.common.annotations.VisibleForTesting;
import java.io.File;
import java.util.Optional;
import java.util.function.Function;

public final class AzureEventHubConnectionTestlet implements Testlet {
   private static final String TESTLET_TITLE = "Azure Event Hub Connection Testlet";
   private final Function<AzureEventHubConnectionTestlet.TestletInput, EventHubClient> clientSupplier;
   private Optional<EventHubClient> eventHubClient = Optional.empty();

   public AzureEventHubConnectionTestlet() {
      this.clientSupplier = this.defaultClientSupplier();
   }

   @VisibleForTesting
   AzureEventHubConnectionTestlet(EventHubClient client) {
      this.eventHubClient = Optional.of(client);
      this.clientSupplier = var1x -> client;
   }

   private Function<AzureEventHubConnectionTestlet.TestletInput, EventHubClient> defaultClientSupplier() {
      return input -> {
         try {
            AzureMessageBrokerConnectorSettings.AzureMessageBrokerConnectorSettingsBuilder settings = AzureMessageBrokerConnectorSettings.builder()
               .eventHubNamespace(StringPropertyValueReader.effectiveStringConfigValue(input.pc, "eventHubNamespace", input.env, input.ctx))
               .eventHubName(StringPropertyValueReader.effectiveStringConfigValue(input.pc, "eventHubName", input.env, input.ctx))
               .authentication(authenticationSettings(input.pc, input.env, input.ctx))
               .connectionString(PasswordPropertyValueReader.effectivePasswordConfigValue(input.pc, "connectionString", input.env, input.ctx))
               .transportType((AmqpTransportType)EnumPropertyValueReader.effectiveConfigEnum(input.pc, "transportType", input.env, input.ctx))
               .proxySettings(proxySettings(input.pc, input.env, input.ctx));
            EventHubClient client = AzureEventHubClientFactory.eventHubClient(settings.build());
            this.eventHubClient = Optional.of(client);
            return client;
         } catch (InitializeException var4) {
            return null;
         }
      };
   }

   public TestletResult performTest(PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context) {
      try (EventHubClient client = this.clientSupplier.apply(new AzureEventHubConnectionTestlet.TestletInput(config, env, context))) {
         client.testConnection();
         return new TestletResult(TestResult.SUCCESSFUL, "Azure Event Hub Connection Testlet", "Connection to Azure Event Hub succeeded.");
      } catch (Exception e) {
         return new TestletResult(TestResult.FAILED, "Azure Event Hub Connection Testlet", "Connection to Azure Event Hub failed.<p>" + e.getMessage() + "</p>");
      }
   }

   public void close() {
      this.eventHubClient.ifPresent(EventHubClient::close);
   }

   private static AzureProxySettings proxySettings(PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context) throws PropertyTypeMismatchException, PropertyConstraintViolationException {
      String host = StringPropertyValueReader.effectiveStringConfigValue(config, "proxyHost", env, context);
      return host == null
         ? null
         : AzureProxySettings.builder()
            .host(host)
            .port(IntegerPropertyValueReader.effectiveIntegerConfigValue(config, "proxyPort", env, context))
            .authenticationType((ProxyAuthenticationType)EnumPropertyValueReader.effectiveConfigEnum(config, "proxyAuthenticationType", env, context))
            .user(StringPropertyValueReader.effectiveStringConfigValue(config, "proxyLoginUser", env, context))
            .password(PasswordPropertyValueReader.effectivePasswordConfigValue(config, "proxyLoginPassword", env, context))
            .build();
   }

   private static AzureAuthenticationSettings authenticationSettings(PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context) throws PropertyTypeMismatchException {
      PluginConfiguration plugin = PluginPropertyValueReader.effectivePluginPropertyValue(config, "authentication", env, context);
      if (plugin == null) {
         return null;
      }

      try {
         Class<?> pluginClass = plugin.getPluginClass();
         if (pluginClass.equals(AzureDefaultAuthenticationConfig.class)) {
            return new AzureAuthenticationSettings.DefaultAuthenticationSettings();
         }

         if (pluginClass.equals(AzureClientSecretAuthenticationConfig.class)) {
            return clientSecretAuthenticationSettings(env, context, plugin);
         }

         if (pluginClass.equals(AzureCertificateAuthenticationConfig.class)) {
            return certificateAuthenticationSettings(env, context, plugin);
         }
      } catch (InitializeException var5) {
      }

      return null;
   }

   private static AzureAuthenticationSettings.ClientSecretAuthenticationSettings clientSecretAuthenticationSettings(
      ConfigurationEnvironment env, ConfigurationContext context, PluginConfiguration plugin
   ) throws PropertyTypeMismatchException {
      return AzureAuthenticationSettings.ClientSecretAuthenticationSettings.builder()
         .tenantId(StringPropertyValueReader.effectiveStringConfigValue(plugin, "tenantId", env, context))
         .clientId(StringPropertyValueReader.effectiveStringConfigValue(plugin, "clientId", env, context))
         .clientSecret(PasswordPropertyValueReader.effectivePasswordConfigValue(plugin, "clientSecret", env, context))
         .build();
   }

   private static AzureAuthenticationSettings.CertificateAuthenticationSettings certificateAuthenticationSettings(
      ConfigurationEnvironment env, ConfigurationContext context, PluginConfiguration plugin
   ) throws PropertyTypeMismatchException {
      return AzureAuthenticationSettings.CertificateAuthenticationSettings.builder()
         .tenantId(StringPropertyValueReader.effectiveStringConfigValue(plugin, "tenantId", env, context))
         .clientId(StringPropertyValueReader.effectiveStringConfigValue(plugin, "clientId", env, context))
         .certificate(new File(FilePropertyValueReader.effectiveFilePropertyValue(plugin, "keystore", env, context)))
         .password(PasswordPropertyValueReader.effectivePasswordConfigValue(plugin, "keystorePassword", env, context))
         .build();
   }

   public boolean areRequiredPropertiesConfigured(PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context) {
      try {
         String eventHubNamespace = StringPropertyValueReader.effectiveStringConfigValue(config, "eventHubNamespace", env, context);
         String eventHubName = StringPropertyValueReader.effectiveStringConfigValue(config, "eventHubName", env, context);
         if (eventHubNamespace != null && eventHubName != null) {
            PluginConfiguration authentication = PluginPropertyValueReader.effectivePluginPropertyValue(config, "authentication", env, context);
            String connectionString = PasswordPropertyValueReader.effectivePasswordConfigValue(config, "connectionString", env, context);
            if (authentication == null && connectionString == null) {
               return false;
            }

            if (authentication != null && !areRequiredAuthenticationPropertiesConfigured(authentication, env, context)) {
               return false;
            }

            String proxyHost = StringPropertyValueReader.effectiveStringConfigValue(config, "proxyHost", env, context);
            Integer proxyPort = IntegerPropertyValueReader.effectiveIntegerConfigValue(config, "proxyPort", env, context);
            return (proxyHost == null || proxyPort != null) && (proxyHost != null || proxyPort == null);
         } else {
            return false;
         }
      } catch (PropertyConfigurationException var10) {
         return false;
      }
   }

   private static boolean areRequiredAuthenticationPropertiesConfigured(PluginConfiguration plugin, ConfigurationEnvironment env, ConfigurationContext ctx) {
      try {
         Class<?> pluginClass = plugin.getPluginClass();
         if (pluginClass.equals(AzureDefaultAuthenticationConfig.class)) {
            return true;
         }

         if (pluginClass.equals(AzureClientSecretAuthenticationConfig.class)) {
            return StringPropertyValueReader.effectiveStringConfigValue(plugin, "tenantId", env, ctx) != null
               && StringPropertyValueReader.effectiveStringConfigValue(plugin, "clientId", env, ctx) != null
               && PasswordPropertyValueReader.effectivePasswordConfigValue(plugin, "clientSecret", env, ctx) != null;
         }

         if (pluginClass.equals(AzureCertificateAuthenticationConfig.class)) {
            return StringPropertyValueReader.effectiveStringConfigValue(plugin, "tenantId", env, ctx) != null
               && StringPropertyValueReader.effectiveStringConfigValue(plugin, "clientId", env, ctx) != null
               && FilePropertyValueReader.effectiveFilePropertyValue(plugin, "keystore", env, ctx) != null
               && PasswordPropertyValueReader.effectivePasswordConfigValue(plugin, "keystorePassword", env, ctx) != null;
         }
      } catch (InitializeException var4) {
      }

      return true;
   }

   public String getRequiredPropertiesMissingMessage() {
      return "Please configure all mandatory properties.";
   }

   public TestletType getType() {
      return TestletType.RESULT;
   }

   private record TestletInput(PluginConfiguration pc, ConfigurationEnvironment env, ConfigurationContext ctx) {
   }
}
