package com.airlock.iam.common.domain.model.valueprovider;

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.common.api.domain.model.valueprovider.ValueProvider;
import com.airlock.iam.common.application.configuration.valueprovider.FallbackStringValueProviderConfig;
import com.airlock.iam.elog.api.EDefaultLogType;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.List;

@LogicForConfig(FallbackStringValueProviderConfig.class)
public final class FallbackStringValueProvider implements ValueProvider<String> {
   private static final ELogger LOG = ELoggerFactory.getLogger(FallbackStringValueProvider.class);
   private final Provider<List<ValueProvider<String>>> stringValueProviders;
   private final Provider<TreatEmptyStringAsNull> treatEmptyStringAsNullProvider;

   @Inject
   public FallbackStringValueProvider(
      Provider<List<ValueProvider<String>>> stringValueProviders, Provider<TreatEmptyStringAsNull> treatEmptyStringAsNullProvider
   ) {
      this.stringValueProviders = stringValueProviders;
      this.treatEmptyStringAsNullProvider = treatEmptyStringAsNullProvider;
   }

   @Nullable
   public String getValue() {
      boolean treatEmptyStringAsNull = ((TreatEmptyStringAsNull)this.treatEmptyStringAsNullProvider.get()).value();

      for (ValueProvider<String> stringValueProvider : (List)this.stringValueProviders.get()) {
         try {
            String providerValue = stringValueProvider.getValue();
            if (providerValue != null && (!treatEmptyStringAsNull || !providerValue.isEmpty())) {
               return providerValue;
            }
         } catch (Exception e) {
            LOG.warn(EDefaultLogType.GENERIC_LOG_TYPE, "a fallback value provider encountered an error - the value provider is ignored: " + e.getMessage());
         }
      }

      return null;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class FallbackStringValueProviderBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private Provider<List<ValueProvider<String>>> stringValueProviders;
      @SuppressFBWarnings(justification = "generated code")
      private Provider<TreatEmptyStringAsNull> treatEmptyStringAsNullProvider;

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

      @SuppressFBWarnings(justification = "generated code")
      public FallbackStringValueProvider.FallbackStringValueProviderBuilder stringValueProviders(Provider<List<ValueProvider<String>>> stringValueProviders) {
         this.stringValueProviders = stringValueProviders;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public FallbackStringValueProvider.FallbackStringValueProviderBuilder treatEmptyStringAsNullProvider(
         Provider<TreatEmptyStringAsNull> treatEmptyStringAsNullProvider
      ) {
         this.treatEmptyStringAsNullProvider = treatEmptyStringAsNullProvider;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public FallbackStringValueProvider build() {
         return new FallbackStringValueProvider(this.stringValueProviders, this.treatEmptyStringAsNullProvider);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "FallbackStringValueProvider.FallbackStringValueProviderBuilder(stringValueProviders="
            + this.stringValueProviders
            + ", treatEmptyStringAsNullProvider="
            + this.treatEmptyStringAsNullProvider
            + ")";
      }
   }
}
