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

import com.airlock.iam.base.misc.result.Result;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.factor.domain.model.airlock2fa.Airlock2FAAuthTokenId;
import com.airlock.iam.factor.domain.model.airlock2fa.Airlock2FAAuthTokenIdCoder;
import com.airlock.iam.factor.domain.service.airlock2fa.Airlock2FAApprovalAuthTokenIdService;
import com.airlock.iam.factor.domain.service.airlock2fa.Airlock2FAApprovalAuthTokenIdService.Airlock2FAAuthTokenIdFailure;
import com.airlock.iam.flow.api.domain.model.session.FlowAttributeRepository;
import com.airlock.iam.flow.shared.domain.model.attributes.AuthTokenIdAttribute;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Optional;

public final class Airlock2FATransactionApprovalAuthTokenIdServiceImpl implements Airlock2FAApprovalAuthTokenIdService {
   private static final ELogger LOG = ELoggerFactory.getLogger(Airlock2FATransactionApprovalAuthTokenIdServiceImpl.class);
   private final Provider<Airlock2FAAuthTokenIdCoder> coder;
   private final Provider<FlowAttributeRepository> flowAttributes;

   @Inject
   public Airlock2FATransactionApprovalAuthTokenIdServiceImpl(Provider<Airlock2FAAuthTokenIdCoder> coder, Provider<FlowAttributeRepository> flowAttributes) {
      this.coder = coder;
      this.flowAttributes = flowAttributes;
   }

   public Result<Airlock2FAAuthTokenId, Airlock2FAAuthTokenIdFailure> loadAuthTokenId() {
      Optional<AuthTokenIdAttribute> attribute = ((FlowAttributeRepository)this.flowAttributes.get()).tryGetAttribute(AuthTokenIdAttribute.class);
      if (attribute.isEmpty()) {
         return Result.failure(Airlock2FAAuthTokenIdFailure.NOT_PRESENT);
      } else {
         String encodedAuthTokenId = attribute.get().getAuthTokenId();
         Optional<Airlock2FAAuthTokenId> authTokenId = ((Airlock2FAAuthTokenIdCoder)this.coder.get()).decode(encodedAuthTokenId);
         if (authTokenId.isEmpty()) {
            LOG.info("Used device info could not be decoded (wrong format or unknown login factor): " + encodedAuthTokenId);
            return Result.failure(Airlock2FAAuthTokenIdFailure.INVALID_FORMAT);
         } else {
            LOG.debug("Loaded used factor and device from Auth Token ID: " + authTokenId.get());
            return Result.result(authTokenId.get());
         }
      }
   }
}
