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

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.flow.shared.api.domain.model.valueprovider.ValueMapProvider;
import com.airlock.iam.flow.shared.api.domain.service.FlowAttributeService;
import com.airlock.iam.flow.shared.application.configuration.valueprovider.AuthenticationDataValueMapProviderConfig;
import com.airlock.iam.flow.shared.domain.model.attributes.AuthTokenIdFlowSessionAttribute;
import com.airlock.iam.flow.shared.domain.model.session.SuccessfulAuthenticationTimestamp;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@LogicForConfig(AuthenticationDataValueMapProviderConfig.class)
public class AuthenticationDataValueMapProvider implements ValueMapProvider {
   private final Provider<Optional<SuccessfulAuthenticationTimestamp>> authenticationTimestamp;
   private final Provider<FlowAttributeService> attributes;

   @Inject
   public AuthenticationDataValueMapProvider(
      Provider<Optional<SuccessfulAuthenticationTimestamp>> authenticationTimestamp, Provider<FlowAttributeService> attributes
   ) {
      this.authenticationTimestamp = authenticationTimestamp;
      this.attributes = attributes;
   }

   @Override
   public Map<String, Object> provideValueMap() {
      Map<String, Object> map = new HashMap<>();
      ((Optional)this.authenticationTimestamp.get())
         .map(SuccessfulAuthenticationTimestamp::getAuthenticationTime)
         .map(Date::from)
         .ifPresent(date -> map.put("authentication-timestamp", date));
      ((Optional)this.authenticationTimestamp.get())
         .map(SuccessfulAuthenticationTimestamp::getAuthenticationTime)
         .ifPresent(instant -> map.put("authentication-timestamp-millis", instant.toEpochMilli()));
      this.findAuthTokenId().map(AuthTokenIdFlowSessionAttribute::getAuthTokenId).ifPresent(authTokenId -> map.put("auth-token-id", authTokenId));
      return Map.copyOf(map);
   }

   private Optional<AuthTokenIdFlowSessionAttribute> findAuthTokenId() {
      return ((FlowAttributeService)this.attributes.get()).findAttribute(AuthTokenIdFlowSessionAttribute.class);
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class AuthenticationDataValueMapProviderBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private Provider<Optional<SuccessfulAuthenticationTimestamp>> authenticationTimestamp;
      @SuppressFBWarnings(justification = "generated code")
      private Provider<FlowAttributeService> attributes;

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

      @SuppressFBWarnings(justification = "generated code")
      public AuthenticationDataValueMapProvider.AuthenticationDataValueMapProviderBuilder authenticationTimestamp(
         Provider<Optional<SuccessfulAuthenticationTimestamp>> authenticationTimestamp
      ) {
         this.authenticationTimestamp = authenticationTimestamp;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public AuthenticationDataValueMapProvider.AuthenticationDataValueMapProviderBuilder attributes(Provider<FlowAttributeService> attributes) {
         this.attributes = attributes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public AuthenticationDataValueMapProvider build() {
         return new AuthenticationDataValueMapProvider(this.authenticationTimestamp, this.attributes);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "AuthenticationDataValueMapProvider.AuthenticationDataValueMapProviderBuilder(authenticationTimestamp="
            + this.authenticationTimestamp
            + ", attributes="
            + this.attributes
            + ")";
      }
   }
}
