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

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.base.api.infrastructure.plugin.ModuleForConfig;
import com.airlock.iam.factor.domain.model.fido.FidoApprovalData;
import com.airlock.iam.flow.api.domain.model.session.FlowAttributeRepository;
import com.airlock.iam.flow.shared.application.configuration.fido.FidoApprovalStepErrors;
import com.airlock.iam.flow.shared.domain.model.fido.FidoCheckingStep.FidoStepActions;
import com.airlock.iam.flow.shared.domain.model.fido.FidoCheckingStep.FidoStepErrors;
import com.airlock.iam.flow.shared.domain.model.fido.FidoCheckingStepImpl.FidoTransactionApprovalStepSettings;
import com.airlock.iam.flow.shared.infrastructure.factory.step.FidoStepModuleForConfigBase;
import com.airlock.iam.transactionapproval.application.configuration.fido.FidoTransactionApprovalStepActions;
import com.airlock.iam.transactionapproval.application.configuration.fido.FidoTransactionApprovalStepConfig;
import com.airlock.iam.transactionapproval.domain.model.flow.TransactionApprovalMessageAttributes;
import com.google.inject.Exposed;
import com.google.inject.Provides;
import java.util.Optional;

@ModuleForConfig(FidoTransactionApprovalStepConfig.class)
public class FidoTransactionApprovalStepModule extends FidoStepModuleForConfigBase {
   @Provides
   @Exposed
   FidoStepActions provideFidoStepActions() {
      return FidoTransactionApprovalStepActions.FIDO_TRX_APPROVAL_STEP_ACTIONS;
   }

   @Provides
   @Exposed
   FidoStepErrors provideFidoStepErrors() {
      return FidoApprovalStepErrors.FIDO_APPROVAL_STEP_ERRORS;
   }

   @Provides
   @Exposed
   Optional<FidoApprovalData> provideFidoApprovalData(FlowAttributeRepository attributes) {
      return Optional.of(
         new FidoApprovalData(
            ((TransactionApprovalMessageAttributes)attributes.tryGetAttribute(TransactionApprovalMessageAttributes.class)
                  .orElseThrow(
                     () -> new FailureException(
                        "No TransactionApprovalMessageAttributes present. Make sure there is a TransactionApprovalParameterStep configured in the flow."
                     )
                  ))
               .getAttributes()
         )
      );
   }

   @Provides
   @Exposed
   FidoTransactionApprovalStepSettings provideFidoCheckingStepSettings(FidoTransactionApprovalStepConfig config) {
      return FidoTransactionApprovalStepSettings.builder().verificationLogging(config.isVerificationLogging()).build();
   }

   protected void configure() {
      super.configure();
   }
}
