package com.airlock.iam.login.app.infrastructure.session;

import com.airlock.iam.base.api.domain.model.mapification.MapifiedValues;
import com.airlock.iam.base.domain.model.mapification.LazySupplier;
import com.airlock.iam.common.domain.model.session.ReadOnlyUserSessionData;
import com.airlock.iam.flow.shared.domain.model.session.LazyUserSession;
import com.airlock.iam.flow.shared.domain.model.session.UserSessionImpl;
import com.airlock.iam.flow.shared.domain.service.session.ReadOnlyUserSessionDataFactory;
import com.airlock.iam.saml2.domain.model.session.FlowFederationSession;
import jakarta.inject.Inject;
import java.util.Objects;
import java.util.Optional;

public class LoginappReadOnlyUserSessionDataFactory implements ReadOnlyUserSessionDataFactory {
   @Override
   public Optional<ReadOnlyUserSessionData> readOnlyUserSessionData(LazyUserSession session) {
      return session.getSupplier()
         .map(
            supplier -> new ReadOnlyUserSessionData(
               session.getUserId(), this.extractBlockRequests((LazySupplier<MapifiedValues, UserSessionImpl>)supplier).orElse(false)
            )
         );
   }

   private Optional<Boolean> extractBlockRequests(LazySupplier<MapifiedValues, UserSessionImpl> supplier) {
      return supplier.hasBeenSupplied() ? this.extractBlockRequestsFromAlreadySupplied(supplier.get()) : this.extractBlockRequestsFromRaw(supplier);
   }

   private Optional<Boolean> extractBlockRequestsFromRaw(LazySupplier<MapifiedValues, UserSessionImpl> supplier) {
      return supplier.getRawValue()
         .<MapifiedValues>getList("attrs")
         .stream()
         .filter(map -> Objects.equals(map.get("class"), FlowFederationSession.class.getName()))
         .findFirst()
         .map(x -> x.getValues("values"))
         .map(FlowFederationSession::demapify)
         .map(FlowFederationSession::isBlockRestRequests);
   }

   private Optional<Boolean> extractBlockRequestsFromAlreadySupplied(UserSessionImpl userSession) {
      return userSession.findUserSessionAttribute(FlowFederationSession.class).map(FlowFederationSession::isBlockRestRequests);
   }
}
