/**
   * Log an authentication process successful completion event.
   *
   * @param loginState The login state object.
   */
  public void auditLoginSuccess(LoginState loginState) {
    String realm = getRealmFromState(loginState);

    if (eventPublisher.isAuditing(realm, AUTHENTICATION_TOPIC)) {
      String moduleName = null;
      String userDN = null;
      if (loginState != null) {
        moduleName = loginState.getAuthModuleNames();
        userDN = loginState.getUserDN();
      }

      AMAuthenticationAuditEventBuilder builder =
          eventFactory
              .authenticationEvent()
              .transactionId(getTransactionIdValue())
              .component(AUTHENTICATION)
              .eventName(AM_LOGIN_COMPLETED)
              .result(SUCCESSFUL)
              .realm(realm)
              .entry(getAuditEntryDetail(moduleName, loginState))
              .trackingIds(getTrackingIds(loginState))
              .userId(userDN == null ? "" : userDN)
              .principal(DNUtils.DNtoName(userDN));

      eventPublisher.tryPublish(AUTHENTICATION_TOPIC, builder.toEvent());
    }
  }
  /**
   * Log an authentication process failure event.
   *
   * @param loginState The login state object.
   * @param failureReason The reason for the failure. If {@literal failureReason} is null then the
   *     value of {@link LoginState#getErrorCode()} will be mapped to an {@link
   *     AuthenticationFailureReason} with {@link AuthenticationFailureReason#LOGIN_FAILED} as
   *     default if the value could not be mapped.
   */
  public void auditLoginFailure(LoginState loginState, AuthenticationFailureReason failureReason) {
    String realm = getRealmFromState(loginState);

    if (eventPublisher.isAuditing(realm, AUTHENTICATION_TOPIC)) {
      String principal = getFailedPrincipal(loginState);
      String moduleName = loginState == null ? null : loginState.getFailureModuleNames();
      AuthenticationAuditEntry entryDetail = getAuditEntryDetail(moduleName, loginState);
      if (failureReason == null) {
        failureReason = findFailureReason(loginState);
      }
      entryDetail.addInfo(FAILURE_REASON, failureReason.name());

      AMAuthenticationAuditEventBuilder builder =
          eventFactory
              .authenticationEvent()
              .transactionId(getTransactionIdValue())
              .component(AUTHENTICATION)
              .eventName(AM_LOGIN_COMPLETED)
              .result(FAILED)
              .realm(realm)
              .entry(entryDetail)
              .trackingIds(getTrackingIds(loginState))
              .userId(getUserId(principal, realm))
              .principal(principal);

      eventPublisher.tryPublish(AUTHENTICATION_TOPIC, builder.toEvent());
    }
  }
  /**
   * Log a logout event.
   *
   * @param token The {@Link SSOToken} of the event.
   */
  public void auditLogout(SSOToken token) {
    String realm = getRealmFromToken(token);

    if (eventPublisher.isAuditing(realm, AUTHENTICATION_TOPIC)) {
      String principalName;
      try {
        Principal principal = token == null ? null : token.getPrincipal();
        principalName = principal == null ? null : DNUtils.DNtoName(principal.getName());
      } catch (SSOException e) {
        principalName = null;
      }

      AuthenticationAuditEntry entryDetail = new AuthenticationAuditEntry();
      entryDetail.setModuleId(getSSOTokenProperty(token, AUTH_TYPE));

      String host = getSSOTokenProperty(token, HOST);
      if (isNotEmpty(host)) {
        entryDetail.addInfo(IP_ADDRESS, host);
      }

      String trackingId = getTrackingIdFromSSOToken(token);
      String userId = AMAuditEventBuilderUtils.getUserId(token);

      AMAuthenticationAuditEventBuilder builder =
          eventFactory
              .authenticationEvent()
              .transactionId(getTransactionIdValue())
              .component(AUTHENTICATION)
              .eventName(AM_LOGOUT)
              .result(SUCCESSFUL)
              .realm(realm)
              .entry(entryDetail)
              .trackingId(trackingId == null ? "" : trackingId)
              .userId(userId == null ? "" : userId)
              .principal(principalName);

      eventPublisher.tryPublish(AUTHENTICATION_TOPIC, builder.toEvent());
    }
  }