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

import com.airlock.iam.base.api.infrastructure.plugin.ModuleForConfig;
import com.airlock.iam.common.api.domain.model.location.transform.StringTransformer;
import com.airlock.iam.common.domain.model.location.transform.LowercaseStringTransformer;
import com.airlock.iam.common.domain.model.transform.TransformationProcessor;
import com.airlock.iam.login.api.domain.model.location.extract.URIValueExtractor;
import com.airlock.iam.login.application.configuration.location.interpret.SimpleLocationInterpreterConfig;
import com.airlock.iam.login.domain.model.location.extract.QueryParameterURIValueExtractor;
import com.airlock.iam.login.domain.model.location.extract.RegexURIValueExtractor;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import java.net.URI;
import java.util.List;
import java.util.Optional;

@ModuleForConfig(SimpleLocationInterpreterConfig.class)
public class SimpleLocationInterpreterModule extends PrivateModule {
   @Provides
   @Exposed
   Optional<String> provideDefaultValue(SimpleLocationInterpreterConfig config) {
      return config.getDefaultValue();
   }

   @Provides
   @Exposed
   TransformationProcessor<URI> provideURITransformationProcessor() {
      return new TransformationProcessor<>(List.of());
   }

   @Provides
   @Exposed
   TransformationProcessor<String> provideStringTransformationProcessor(SimpleLocationInterpreterConfig config) {
      return new TransformationProcessor<>(createStringTransformers(config));
   }

   @Provides
   @Exposed
   List<URIValueExtractor> getValueExtractors(SimpleLocationInterpreterConfig config) {
      if (config.getFromQueryParam() != null) {
         return List.of(new QueryParameterURIValueExtractor(config.getFromQueryParam(), List.of()));
      } else if (config.getWithUrlRegex() != null) {
         return List.of(new RegexURIValueExtractor(config.getWithUrlRegex()));
      } else {
         throw new IllegalStateException("One of the two values is always configured");
      }
   }

   private static List<StringTransformer> createStringTransformers(SimpleLocationInterpreterConfig config) {
      return config.isTransformToLowercase() ? List.of(new LowercaseStringTransformer()) : List.of();
   }

   protected void configure() {
   }
}
