package com.airlock.iam.transactionapproval.infrastructure.factory;

import com.airlock.iam.common.domain.model.session.IamSession;
import com.airlock.iam.common.domain.model.session.ReadOnlyIamSessionData;
import com.airlock.iam.common.domain.model.session.SessionId;
import com.airlock.iam.common.domain.service.SessionIdService;
import com.airlock.iam.common.domain.service.session.IamSessionService;
import com.airlock.iam.common.infrastructure.filter.general.IamSessionProcessing;
import com.airlock.iam.common.infrastructure.session.SessionIdServiceImpl;
import com.airlock.iam.flow.domain.model.session.StateMachineHolder;
import com.airlock.iam.flow.shared.domain.model.session.FlowBasedIamSession;
import com.airlock.iam.flow.shared.domain.service.session.ReadOnlyIamSessionDataFactory;
import com.airlock.iam.flow.shared.infrastructure.session.FlowBasedIamSessionProcessing;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import com.google.inject.servlet.RequestScoped;
import java.util.Optional;

public final class TransactionApprovalIamSessionModule extends PrivateModule {
   @Provides
   @RequestScoped
   @Exposed
   SessionId provideSessionId(IamSession iamSession) {
      return iamSession.sessionId();
   }

   @Provides
   @RequestScoped
   @Exposed
   FlowBasedIamSession provideIamSession(IamSessionService<FlowBasedIamSession> sessionService) {
      return (FlowBasedIamSession)sessionService.retrieveOrCreateSession();
   }

   @Provides
   @RequestScoped
   @Exposed
   Optional<ReadOnlyIamSessionData> provideReadOnlyIamSessionData(ReadOnlyIamSessionDataFactory readOnlyFactory, FlowBasedIamSession iamSession) {
      return Optional.of(readOnlyFactory.readOnlyIamSessionData(iamSession));
   }

   protected void configure() {
      this.bind(IamSessionProcessing.class).to(FlowBasedIamSessionProcessing.class).in(RequestScoped.class);
      this.expose(IamSessionProcessing.class);
      this.bind(SessionIdService.class).to(SessionIdServiceImpl.class);
      this.expose(SessionIdService.class);
      this.bind(IamSession.class).to(FlowBasedIamSession.class).in(RequestScoped.class);
      this.expose(IamSession.class);
      this.bind(StateMachineHolder.class).to(FlowBasedIamSession.class).in(RequestScoped.class);
      this.expose(StateMachineHolder.class);
   }
}
