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.exception.ViolationException;
import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.base.misc.date.Dates;
import com.airlock.iam.common.api.domain.model.valueprovider.ValueProvider;
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.DateAndTimeFromMapValueProviderConfig;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.time.Instant;
import java.util.Date;

@LogicForConfig(DateAndTimeFromMapValueProviderConfig.class)
public class DateAndTimeFromMapValueProvider extends EntryFromMapValueProvider implements ValueProvider<Date> {
   private static final ELogger LOG = ELoggerFactory.getLogger(DateAndTimeFromMapValueProvider.class);

   @Inject
   protected DateAndTimeFromMapValueProvider(Provider<ValueMapProviderList> valueMapProviderList, Provider<EntryFromMapValueProviderSettings> settings) {
      super(valueMapProviderList, settings);
   }

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

      return switch (unidentified) {
         case null -> null;
         case Date date -> date;
         case Instant instant -> Date.from(instant);
         case String str -> this.parseDateTimeString(str);
         default -> throw new FailureException(
            "Cannot convert value with key '"
               + this.getEntryKey()
               + "' to a valid date and time representation. Actual type: "
               + unidentified.getClass().getSimpleName()
         );
      };
   }

   private Date parseDateTimeString(String str) {
      try {
         return Dates.toDate(str);
      } catch (ViolationException e) {
         LOG.debug(
            "Failed to convert string of key '" + this.getEntryKey() + "' to a valid date and time. Provided value: \"" + str + "\", Cause: " + e.getMessage()
         );
         throw new FailureException("Failed to convert string of key '" + this.getEntryKey() + "' to a valid date and time.");
      }
   }
}
