package com.airlock.iam.saml2.infrastructure.session;

import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.saml2.domain.model.session.FlowFederationSession;
import com.airlock.iam.saml2.domain.model.session.FlowFederationSessionUsage;
import com.airlock.iam.saml2.domain.service.Saml2LibraryIdpCacheService;
import com.sun.identity.saml2.common.AccountUtils;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;

public final class FlowFederationSessionUsageImpl implements FlowFederationSessionUsage {
   private static final ELogger LOG = ELoggerFactory.getLogger(FlowFederationSessionUsageImpl.class);
   private final Provider<Saml2LibraryIdpCacheService> libraryCache;

   @Inject
   FlowFederationSessionUsageImpl(Provider<Saml2LibraryIdpCacheService> libraryCache) {
      this.libraryCache = libraryCache;
   }

   @Override
   public Optional<FlowFederationSessionUsage.FlowFederationSessionType> usageOf(FlowFederationSession session) {
      boolean usedByIdp = session.isSingleLogoutInProgressOnIdp()
         || session.getSessionIndex().map(index -> ((Saml2LibraryIdpCacheService)this.libraryCache.get()).isSessionIndexCached(index)).orElse(false);
      boolean usedBySp = session.isSingleLogoutInProgressOnSp()
         || session.getValues(AccountUtils.getNameIDInfoKeyAttribute()).map(list -> list.getFirst()).filter(StringUtils::isNotBlank).isPresent();
      if (usedByIdp && usedBySp) {
         LOG.info("SAML 2.0 flow federation session is used both by IAM acting as SP and IAM acting as IdP");
         return Optional.of(FlowFederationSessionUsage.FlowFederationSessionType.IDP_AND_SP);
      } else if (usedByIdp) {
         return Optional.of(FlowFederationSessionUsage.FlowFederationSessionType.IDP_ONLY);
      } else {
         return usedBySp ? Optional.of(FlowFederationSessionUsage.FlowFederationSessionType.SP_ONLY) : Optional.empty();
      }
   }
}
