package com.airlock.iam.common.infrastructure.event;

import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.base.domain.model.event.SubscribedEvent;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.common.api.domain.model.event.UserEvent;
import com.airlock.iam.common.domain.service.gateway.GatewaySessionTerminatorEventSubscriber;
import com.airlock.iam.common.domain.service.gateway.GatewaySessionTerminatorSessionFilter;
import com.airlock.iam.common.infrastructure.gateway.GatewayRestApi;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.List;
import java.util.function.Predicate;

public class DefaultGatewaySessionTerminatorEventSubscriber implements GatewaySessionTerminatorEventSubscriber {
   private static final ELogger LOG = ELoggerFactory.getLogger(DefaultGatewaySessionTerminatorEventSubscriber.class);
   private final Provider<SubscribedEvent> subscribedEvent;
   private final Provider<List<GatewayRestApi>> gatewayAdminRestApis;
   private final Provider<GatewaySessionTerminatorSessionFilter> sessionFilter;

   @Inject
   public DefaultGatewaySessionTerminatorEventSubscriber(
      Provider<SubscribedEvent> subscribedEvent,
      Provider<List<GatewayRestApi>> gatewayAdminRestApis,
      Provider<GatewaySessionTerminatorSessionFilter> sessionFilter
   ) {
      this.subscribedEvent = subscribedEvent;
      this.gatewayAdminRestApis = gatewayAdminRestApis;
      this.sessionFilter = sessionFilter;
   }

   public void handleEvent(UserEvent event) {
      if (((SubscribedEvent)this.subscribedEvent.get()).canHandle(event)) {
         UserId userId = event.userId();
         LOG.info(
            String.format(
               "Received %s event for user %s. Terminating the user's Gateway sessions...",
               LogUtil.logSafeQuote(event.displayName()),
               LogUtil.logSafeQuote(userId)
            )
         );
         ((List)this.gatewayAdminRestApis.get())
            .forEach(gatewayRestApi -> gatewayRestApi.terminateUserSessions(userId.getValue(), (Predicate<String>)this.sessionFilter.get()));
      }
   }

   @Override
   public Class<UserEvent> forType() {
      return UserEvent.class;
   }
}
