package com.airlock.iam.flow.shared.domain.model.valueprovider;

import com.airlock.iam.base.api.domain.model.exception.FailureException;
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.domain.model.valueprovider.BooleanFromMapValueProviderSettings;
import com.airlock.iam.common.domain.model.valueprovider.EntryFromMapValueProviderSettings;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.flow.shared.application.configuration.valueprovider.BooleanFromMapValueProviderConfig;
import jakarta.inject.Inject;
import jakarta.inject.Provider;

@LogicForConfig(BooleanFromMapValueProviderConfig.class)
public class BooleanFromMapValueProvider extends EntryFromMapValueProvider implements ValueProvider<Boolean> {
   private static final ELogger LOG = ELoggerFactory.getLogger(BooleanFromMapValueProvider.class);
   private final Provider<BooleanFromMapValueProviderSettings> additionalSettings;

   @Inject
   protected BooleanFromMapValueProvider(
      Provider<ValueMapProviderList> valueMapProviderList,
      Provider<EntryFromMapValueProviderSettings> settings,
      Provider<BooleanFromMapValueProviderSettings> additionalSettings
   ) {
      super(valueMapProviderList, settings);
      this.additionalSettings = additionalSettings;
   }

   public Boolean getValue() {
      Object unidentified = this.getValueMapEntry();

      return switch (unidentified) {
         case null -> ((BooleanFromMapValueProviderSettings)this.additionalSettings.get()).provideFalseIfEmpty() ? false : null;
         case Boolean bool -> bool;
         case String str -> this.strictParseBoolean(str);
         default -> throw new FailureException(
            "Cannot convert value with key '" + this.getEntryKey() + "' to a valid boolean. Actual type: " + unidentified.getClass().getSimpleName()
         );
      };
   }

   private boolean strictParseBoolean(String str) {
      if (str.equalsIgnoreCase("true")) {
         return true;
      }

      if (str.equalsIgnoreCase("false")) {
         return false;
      }

      LOG.debug("String with key '" + this.getEntryKey() + "' is not a valid boolean format. Provided value: " + str);
      throw new FailureException("String with key '" + this.getEntryKey() + "' is not a valid boolean format (true/false).");
   }
}
