package com.airlock.iam.authentication.infrastructure.factory;

import com.airlock.iam.authentication.application.configuration.identification.UserByDataIdentifyingStepConfig;
import com.airlock.iam.base.api.infrastructure.plugin.ModuleForConfig;
import com.airlock.iam.base.api.infrastructure.plugin.PluginConfigToLogic;
import com.airlock.iam.common.api.domain.model.user.transformation.UsernameTransformation;
import com.airlock.iam.common.domain.model.transform.UsernameTransformerUsernameTransformation;
import com.airlock.iam.flow.shared.application.configuration.FlowUserNameTransformerConfig;
import com.airlock.iam.flow.shared.domain.service.identification.IdentityProvidingByUserDataService;
import com.airlock.iam.flow.shared.domain.service.identification.IdentityProvidingByUserDataServiceImpl;
import com.airlock.iam.flow.shared.domain.service.identification.UserDataService;
import com.airlock.iam.flow.shared.domain.service.identification.UserDataServiceImpl;
import com.airlock.iam.flow.shared.domain.service.identification.UserIdentificationService;
import com.airlock.iam.flow.shared.domain.service.identification.UserIdentificationServiceImpl;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import java.util.Optional;
import java.util.stream.Collectors;

@ModuleForConfig(UserByDataIdentifyingStepConfig.class)
public class UserByDataIdentifyingStepModule extends PrivateModule {
   @Exposed
   @Provides
   IdentityProvidingByUserDataServiceImpl.IdentityProvidingByUserDataServiceSettings provideValidatorsOfContextDataItems(
      UserByDataIdentifyingStepConfig config, PluginConfigToLogic toLogic
   ) {
      return new IdentityProvidingByUserDataServiceImpl.IdentityProvidingByUserDataServiceSettings(
         config.getContextDataItems().stream().map(itemConfig -> toLogic.getLogic(itemConfig)).collect(Collectors.toList()), config.isIgnoreCase()
      );
   }

   @Provides
   UsernameTransformation provideUsernameTransformation(Optional<FlowUserNameTransformerConfig> userNameTransformerConfig) {
      return userNameTransformerConfig.map(FlowUserNameTransformerConfig::getUsernameTransformers)
         .map(UsernameTransformerUsernameTransformation::new)
         .orElse(UsernameTransformation.identity());
   }

   protected void configure() {
      this.bind(IdentityProvidingByUserDataService.class).to(IdentityProvidingByUserDataServiceImpl.class);
      this.bind(UserIdentificationService.class).to(UserIdentificationServiceImpl.class);
      this.expose(IdentityProvidingByUserDataService.class);
      this.bind(UserDataService.class).to(UserDataServiceImpl.class);
   }
}
