package com.airlock.iam.factor.application.service.airlock2fa;

import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.elog.api.EDefaultLogType;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.factor.domain.model.airlock2fa.Airlock2FAUser;
import com.airlock.iam.factor.domain.service.airlock2fa.Airlock2FAAdminApiUserDeleteService;
import com.airlock.iam.factor.domain.service.airlock2fa.repository.Airlock2FAUserRepository;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.function.Consumer;

public final class Airlock2FAConsistencyUserChangeServiceImpl implements Airlock2FAConsistencyUserChangeService {
   private static final ELogger LOG = ELoggerFactory.getLogger(Airlock2FAConsistencyUserChangeServiceImpl.class);
   private final Airlock2FAUserRepository repository;
   private final Airlock2FAAdminApiUserDeleteService userDeleteService;
   private final Consumer<String> auditLogger;

   @Override
   public void delete(UserId userId) {
      this.repository.findBy(userId).ifPresent(airlock2FAUser -> {
         try {
            this.userDeleteService.delete(airlock2FAUser.getAccountId());
         } catch (RuntimeException e) {
            String message = "Could not delete 2FA account " + LogUtil.quote(airlock2FAUser.getAccountId()) + ": ";
            LOG.warn(EDefaultLogType.GENERIC_LOG_TYPE, message, e);
            this.auditLogger.accept(message + e.getMessage());
         }

         this.repository.delete(airlock2FAUser.getAccountId());
      });
   }

   @Override
   public void rename(UserId oldUserId, UserId newUserId) {
      this.repository
         .findBy(oldUserId)
         .map(Airlock2FAUser::getAccountId)
         .ifPresent(accountId -> this.repository.update(Airlock2FAUser.airlock2FAUser(newUserId, accountId)));
   }

   @SuppressFBWarnings(justification = "generated code")
   public Airlock2FAConsistencyUserChangeServiceImpl(
      Airlock2FAUserRepository repository, Airlock2FAAdminApiUserDeleteService userDeleteService, Consumer<String> auditLogger
   ) {
      this.repository = repository;
      this.userDeleteService = userDeleteService;
      this.auditLogger = auditLogger;
   }
}
