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

import com.airlock.iam.common.api.domain.model.authentication.AuthenticationResult;
import com.airlock.iam.common.api.domain.model.user.UserIdentity;
import com.airlock.iam.common.domain.model.authentication.factor.AuthenticationFactorConverter;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.reporting.api.domain.model.data.Action;
import com.airlock.iam.reporting.api.domain.model.data.ActionStatus;
import com.airlock.iam.reporting.api.domain.model.logger.Reporting;
import com.airlock.iam.reporting.domain.model.ReportingDataFactory;

public final class RequestAuthenticationUtil {
   public static void updateLogContext(UserIdentity user) {
      ELoggerFactory.getLogContext().put("UID", user.id().getValue());
      ELoggerFactory.getLogContext().put("PROVIDED_UID", user.providedUsername().getValue());
   }

   public static void reportFactorUsage(Reporting reporting, AuthenticationResult authResult) {
      authResult.authenticationFactorUsages()
         .forEach(
            factorUsage -> reporting.report(
               ReportingDataFactory.dataForFactorUse(
                     AuthenticationFactorConverter.convertFactorUsage(factorUsage), factorUsage.success() ? ActionStatus.SUCCESS : ActionStatus.FAILURE
                  )
                  .build()
            )
         );
   }

   public static void reportAction(Reporting reporting, Action action, AuthenticationResult authResult) {
      authResult.authenticationFactorUsages()
         .forEach(
            factorUsage -> reporting.report(
               ReportingDataFactory.dataForAction(action)
                  .status(factorUsage.success() ? ActionStatus.SUCCESS : ActionStatus.FAILURE)
                  .authnFactor(AuthenticationFactorConverter.convertFactor(factorUsage.factor()))
                  .authnFactorDetail(factorUsage.factorDetail().map(AuthenticationFactorConverter::convertFactorDetail).orElse(null))
                  .build()
            )
         );
   }

   private RequestAuthenticationUtil() {
      throw new AssertionError();
   }
}
