package com.airlock.iam.factor.domain.model.airlock2fa;

import com.airlock.iam.airlock2fa.api.domain.model.Airlock2FAAccountId;
import com.airlock.iam.airlock2fa.api.domain.model.Airlock2FADeviceId;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.factor.domain.model.airlock2fa.activation.Airlock2FAActivationSettings;
import com.airlock.iam.factor.domain.model.airlock2fa.enrollment.Airlock2FAEnrollmentId;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public final class Airlock2FALogData {
   private final Airlock2FAAccountId accountId;
   @Nullable
   private final Airlock2FADeviceId deviceId;
   @Nullable
   private final Airlock2FAEnrollmentId enrollmentId;
   @Nullable
   private final Boolean activationFlowBindingEnabled;
   @Nullable
   private final Boolean recoveryFlowBindingEnabled;
   @Nullable
   private final Boolean provideActivationCodeShortEnabled;

   public static Airlock2FALogData airlock2FALogData(Airlock2FAAccountId accountId) {
      return new Airlock2FALogData(accountId, null, null, null, null, null);
   }

   public Airlock2FALogData withEnrollmentIdIfPresent(Optional<Airlock2FAEnrollmentId> enrollmentId) {
      return enrollmentId.map(this::withEnrollmentId).orElse(this);
   }

   public Airlock2FALogData withActivationSettings(Airlock2FAActivationSettings activationSettings) {
      return this.withActivationFlowBindingEnabled(activationSettings.activationFlowBindingEnabled())
         .withRecoveryFlowBindingEnabled(activationSettings.recoveryFlowBindingEnabled());
   }

   @Override
   public String toString() {
      return Stream.of(
            Stream.of("accountId = " + LogUtil.logSafeQuote(this.accountId.getId())),
            Optional.ofNullable(this.deviceId).stream().map(x -> "deviceId = " + LogUtil.logSafeQuote(x.getId())),
            Optional.ofNullable(this.enrollmentId).stream().map(x -> "enrollmentId = " + LogUtil.logSafeQuote(x.enrollmentId())),
            Optional.ofNullable(this.activationFlowBindingEnabled).stream().map(x -> "activationFlowBindingEnabled = " + LogUtil.logSafeQuote(x)),
            Optional.ofNullable(this.recoveryFlowBindingEnabled).stream().map(x -> "recoveryFlowBindingEnabled = " + LogUtil.logSafeQuote(x)),
            Optional.ofNullable(this.provideActivationCodeShortEnabled).stream().map(x -> "provideActivationCodeShortEnabled = " + LogUtil.logSafeQuote(x))
         )
         .flatMap(Function.identity())
         .collect(Collectors.joining(", ", "(", ")"));
   }

   @SuppressFBWarnings(justification = "generated code")
   private Airlock2FALogData(
      Airlock2FAAccountId accountId,
      @Nullable Airlock2FADeviceId deviceId,
      @Nullable Airlock2FAEnrollmentId enrollmentId,
      @Nullable Boolean activationFlowBindingEnabled,
      @Nullable Boolean recoveryFlowBindingEnabled,
      @Nullable Boolean provideActivationCodeShortEnabled
   ) {
      this.accountId = accountId;
      this.deviceId = deviceId;
      this.enrollmentId = enrollmentId;
      this.activationFlowBindingEnabled = activationFlowBindingEnabled;
      this.recoveryFlowBindingEnabled = recoveryFlowBindingEnabled;
      this.provideActivationCodeShortEnabled = provideActivationCodeShortEnabled;
   }

   @SuppressFBWarnings(justification = "generated code")
   public Airlock2FALogData withAccountId(Airlock2FAAccountId accountId) {
      return this.accountId == accountId
         ? this
         : new Airlock2FALogData(
            accountId,
            this.deviceId,
            this.enrollmentId,
            this.activationFlowBindingEnabled,
            this.recoveryFlowBindingEnabled,
            this.provideActivationCodeShortEnabled
         );
   }

   @SuppressFBWarnings(justification = "generated code")
   public Airlock2FALogData withDeviceId(@Nullable Airlock2FADeviceId deviceId) {
      return this.deviceId == deviceId
         ? this
         : new Airlock2FALogData(
            this.accountId,
            deviceId,
            this.enrollmentId,
            this.activationFlowBindingEnabled,
            this.recoveryFlowBindingEnabled,
            this.provideActivationCodeShortEnabled
         );
   }

   @SuppressFBWarnings(justification = "generated code")
   public Airlock2FALogData withEnrollmentId(@Nullable Airlock2FAEnrollmentId enrollmentId) {
      return this.enrollmentId == enrollmentId
         ? this
         : new Airlock2FALogData(
            this.accountId,
            this.deviceId,
            enrollmentId,
            this.activationFlowBindingEnabled,
            this.recoveryFlowBindingEnabled,
            this.provideActivationCodeShortEnabled
         );
   }

   @SuppressFBWarnings(justification = "generated code")
   public Airlock2FALogData withActivationFlowBindingEnabled(@Nullable Boolean activationFlowBindingEnabled) {
      return this.activationFlowBindingEnabled == activationFlowBindingEnabled
         ? this
         : new Airlock2FALogData(
            this.accountId,
            this.deviceId,
            this.enrollmentId,
            activationFlowBindingEnabled,
            this.recoveryFlowBindingEnabled,
            this.provideActivationCodeShortEnabled
         );
   }

   @SuppressFBWarnings(justification = "generated code")
   public Airlock2FALogData withRecoveryFlowBindingEnabled(@Nullable Boolean recoveryFlowBindingEnabled) {
      return this.recoveryFlowBindingEnabled == recoveryFlowBindingEnabled
         ? this
         : new Airlock2FALogData(
            this.accountId,
            this.deviceId,
            this.enrollmentId,
            this.activationFlowBindingEnabled,
            recoveryFlowBindingEnabled,
            this.provideActivationCodeShortEnabled
         );
   }

   @SuppressFBWarnings(justification = "generated code")
   public Airlock2FALogData withProvideActivationCodeShortEnabled(@Nullable Boolean provideActivationCodeShortEnabled) {
      return this.provideActivationCodeShortEnabled == provideActivationCodeShortEnabled
         ? this
         : new Airlock2FALogData(
            this.accountId,
            this.deviceId,
            this.enrollmentId,
            this.activationFlowBindingEnabled,
            this.recoveryFlowBindingEnabled,
            provideActivationCodeShortEnabled
         );
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean equals(Object o) {
      if (o == this) {
         return true;
      } else if (!(o instanceof Airlock2FALogData other)) {
         return false;
      } else {
         Object this$activationFlowBindingEnabled = this.activationFlowBindingEnabled;
         Object other$activationFlowBindingEnabled = other.activationFlowBindingEnabled;
         if (this$activationFlowBindingEnabled == null
            ? other$activationFlowBindingEnabled == null
            : this$activationFlowBindingEnabled.equals(other$activationFlowBindingEnabled)) {
            Object this$recoveryFlowBindingEnabled = this.recoveryFlowBindingEnabled;
            Object other$recoveryFlowBindingEnabled = other.recoveryFlowBindingEnabled;
            if (this$recoveryFlowBindingEnabled == null
               ? other$recoveryFlowBindingEnabled == null
               : this$recoveryFlowBindingEnabled.equals(other$recoveryFlowBindingEnabled)) {
               Object this$provideActivationCodeShortEnabled = this.provideActivationCodeShortEnabled;
               Object other$provideActivationCodeShortEnabled = other.provideActivationCodeShortEnabled;
               if (this$provideActivationCodeShortEnabled == null
                  ? other$provideActivationCodeShortEnabled == null
                  : this$provideActivationCodeShortEnabled.equals(other$provideActivationCodeShortEnabled)) {
                  Object this$accountId = this.accountId;
                  Object other$accountId = other.accountId;
                  if (this$accountId == null ? other$accountId == null : this$accountId.equals(other$accountId)) {
                     Object this$deviceId = this.deviceId;
                     Object other$deviceId = other.deviceId;
                     if (this$deviceId == null ? other$deviceId == null : this$deviceId.equals(other$deviceId)) {
                        Object this$enrollmentId = this.enrollmentId;
                        Object other$enrollmentId = other.enrollmentId;
                        return this$enrollmentId == null ? other$enrollmentId == null : this$enrollmentId.equals(other$enrollmentId);
                     } else {
                        return false;
                     }
                  } else {
                     return false;
                  }
               } else {
                  return false;
               }
            } else {
               return false;
            }
         } else {
            return false;
         }
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public int hashCode() {
      int PRIME = 59;
      int result = 1;
      Object $activationFlowBindingEnabled = this.activationFlowBindingEnabled;
      result = result * 59 + ($activationFlowBindingEnabled == null ? 43 : $activationFlowBindingEnabled.hashCode());
      Object $recoveryFlowBindingEnabled = this.recoveryFlowBindingEnabled;
      result = result * 59 + ($recoveryFlowBindingEnabled == null ? 43 : $recoveryFlowBindingEnabled.hashCode());
      Object $provideActivationCodeShortEnabled = this.provideActivationCodeShortEnabled;
      result = result * 59 + ($provideActivationCodeShortEnabled == null ? 43 : $provideActivationCodeShortEnabled.hashCode());
      Object $accountId = this.accountId;
      result = result * 59 + ($accountId == null ? 43 : $accountId.hashCode());
      Object $deviceId = this.deviceId;
      result = result * 59 + ($deviceId == null ? 43 : $deviceId.hashCode());
      Object $enrollmentId = this.enrollmentId;
      return result * 59 + ($enrollmentId == null ? 43 : $enrollmentId.hashCode());
   }
}
