package com.airlock.iam.flow.shared.domain.model.cronto;

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.core.misc.impl.token.cronto.CrontoDeviceToken;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

public final class CompleteDeviceActivationResult {
   private final Optional<CrontoDeviceToken> deviceToken;
   private final Optional<CompleteDeviceActivationResult.FailureReason> failureReason;

   public boolean isSuccessful() {
      return this.deviceToken.isPresent();
   }

   public CrontoDeviceToken getDeviceToken() {
      return this.deviceToken.orElseThrow(() -> new FailureException("Cannot get device token from unsuccessful result"));
   }

   public CompleteDeviceActivationResult.FailureReason getFailureReason() {
      return this.failureReason.orElseThrow(() -> new FailureException("Cannot get failure reason from successful result"));
   }

   public static CompleteDeviceActivationResult of(CrontoDeviceToken device) {
      return new CompleteDeviceActivationResult(Optional.of(device), Optional.empty());
   }

   public static CompleteDeviceActivationResult failure(CompleteDeviceActivationResult.FailureReason reason) {
      return new CompleteDeviceActivationResult(Optional.empty(), Optional.of(reason));
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean equals(Object o) {
      if (o == this) {
         return true;
      } else if (!(o instanceof CompleteDeviceActivationResult other)) {
         return false;
      } else {
         Object this$deviceToken = this.deviceToken;
         Object other$deviceToken = other.deviceToken;
         if (this$deviceToken == null ? other$deviceToken == null : this$deviceToken.equals(other$deviceToken)) {
            Object this$failureReason = this.failureReason;
            Object other$failureReason = other.failureReason;
            return this$failureReason == null ? other$failureReason == null : this$failureReason.equals(other$failureReason);
         } else {
            return false;
         }
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public int hashCode() {
      int PRIME = 59;
      int result = 1;
      Object $deviceToken = this.deviceToken;
      result = result * 59 + ($deviceToken == null ? 43 : $deviceToken.hashCode());
      Object $failureReason = this.failureReason;
      return result * 59 + ($failureReason == null ? 43 : $failureReason.hashCode());
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String toString() {
      return "CompleteDeviceActivationResult(deviceToken=" + this.getDeviceToken() + ", failureReason=" + this.getFailureReason() + ")";
   }

   @SuppressFBWarnings(justification = "generated code")
   private CompleteDeviceActivationResult(Optional<CrontoDeviceToken> deviceToken, Optional<CompleteDeviceActivationResult.FailureReason> failureReason) {
      this.deviceToken = deviceToken;
      this.failureReason = failureReason;
   }

   public enum FailureReason {
      CRONTO_OTP_WRONG,
      CRONTO_DEVICE_ALREADY_EXISTS,
      INVALID_CRONTO_LABEL;
   }
}
