package com.airlock.iam.saml2.infrastructure.plugin;

import com.airlock.iam.common.api.application.dependency.injection.LegacyPluginInjectorFactory;
import com.airlock.iam.common.infrastructure.factory.uri.AbsoluteExternalViewUriFactory;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.saml2.application.configuration.Saml2FlowIdpConfig;
import com.airlock.iam.saml2.application.configuration.SamlConfig;
import com.airlock.iam.saml2.domain.model.logging.Saml2LogTypes;
import com.airlock.iam.saml2.infrastructure.idp.Saml2IdpSpaUrls;
import com.airlock.iam.saml2.infrastructure.util.Saml2LoginappConfigProvider;
import com.airlock.iam.saml2.infrastructure.util.Saml2RequestThreadContext;
import com.sun.identity.common.SystemConfigurationException;
import com.sun.identity.common.SystemConfigurationUtil;
import com.sun.identity.shared.configuration.ISystemProperties;
import java.net.URI;
import java.util.List;
import java.util.Optional;
import java.util.Properties;

public final class FlowLoginappSystemPropertiesAdapter implements ISystemProperties {
   private static final ELogger LOG = ELoggerFactory.getLogger(FlowLoginappSystemPropertiesAdapter.class);

   @Override
   public void initializeProperties(Properties properties) {
      LOG.error(Saml2LogTypes.FEDERATION_LIBRARY_MESSAGE, "initializeProperties() not supported");
      throw new UnsupportedOperationException("initializeProperties() not supported");
   }

   public List<String> getServerList() throws SystemConfigurationException {
      return SystemConfigurationUtil.getServerList();
   }

   @Override
   public void initializeProperties(String propertyName, String propertyValue) {
      LOG.error(Saml2LogTypes.FEDERATION_LIBRARY_MESSAGE, "initializeProperties() not supported");
      throw new UnsupportedOperationException("initializeProperties() not supported");
   }

   @Override
   public String get(String key) {
      Optional<SamlConfig> samlSettings = Saml2LoginappConfigProvider.getSamlConfig(Saml2RequestThreadContext.getConfigurationContext());
      if (samlSettings.isEmpty()) {
         throw new IllegalStateException(this.getClass().getSimpleName() + " can not be used without valid SAML2 settings");
      } else if ("AUTH_URI".equals(key)) {
         AbsoluteExternalViewUriFactory uriFactory = LegacyPluginInjectorFactory.getInjector().getInstance(AbsoluteExternalViewUriFactory.class);
         return this.toNullableAsciiString(
            uriFactory,
            samlSettings.flatMap(SamlConfig::getSamlFlowIdpSettings)
               .flatMap(Saml2FlowIdpConfig::getCustomAuthenticationUri)
               .or(() -> Optional.of(Saml2IdpSpaUrls.UI_AUTH_URI.uri()))
         );
      } else if ("ERROR_URI".equals(key)) {
         AbsoluteExternalViewUriFactory uriFactory = LegacyPluginInjectorFactory.getInjector().getInstance(AbsoluteExternalViewUriFactory.class);
         return this.toNullableAsciiString(uriFactory, samlSettings.map(samlConfig -> samlConfig.getSamlFederationConfig().getErrorPageUri()));
      } else {
         Optional<Saml2FlowIdpConfig> idpConf = samlSettings.get().getSamlFlowIdpSettings();
         if ("com.iplanet.am.server.port".equals(key)) {
            return Integer.toString(idpConf.map(Saml2FlowIdpConfig::getPort).orElse(0));
         } else if ("com.iplanet.am.server.protocol".equals(key)) {
            return idpConf.map(Saml2FlowIdpConfig::getProtocol).orElse("https");
         } else if ("com.iplanet.am.server.host".equals(key)) {
            return idpConf.map(Saml2FlowIdpConfig::getHost).orElse("localhost");
         } else {
            return "com.iplanet.am.services.deploymentDescriptor".equals(key)
               ? idpConf.map(Saml2FlowIdpConfig::getContextPath).orElse("")
               : samlSettings.get().getSamlFederationConfig().getProperty(key);
         }
      }
   }

   private String toNullableAsciiString(AbsoluteExternalViewUriFactory uriFactory, Optional<URI> uri) {
      return uri.map(uriFactory::createAbsoluteUri).map(URI::toASCIIString).orElse(null);
   }
}
