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.cronto.CrontoActivationSession;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

public final class StartDeviceActivationResult {
   private final Optional<CrontoActivationSession> activationSession;
   private final Optional<CrontoDeviceActivationChallenge> activationChallenge;
   private final Optional<StartDeviceActivationResult.FailureReason> failureReason;

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

   public CrontoDeviceActivationChallenge getActivationChallenge() {
      return this.activationChallenge.orElseThrow(() -> new FailureException("Cannot get challenge from unsuccessful result"));
   }

   public CrontoActivationSession getActivationSession() {
      return this.activationSession.orElseThrow(() -> new FailureException("Cannot get session from unsuccessful result"));
   }

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

   public static StartDeviceActivationResult of(CrontoActivationSession session, CrontoDeviceActivationChallenge challenge) {
      return new StartDeviceActivationResult(Optional.of(session), Optional.of(challenge), Optional.empty());
   }

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

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean equals(Object o) {
      if (o == this) {
         return true;
      } else if (!(o instanceof StartDeviceActivationResult other)) {
         return false;
      } else {
         Object this$activationSession = this.activationSession;
         Object other$activationSession = other.activationSession;
         if (this$activationSession == null ? other$activationSession == null : this$activationSession.equals(other$activationSession)) {
            Object this$activationChallenge = this.activationChallenge;
            Object other$activationChallenge = other.activationChallenge;
            if (this$activationChallenge == null ? other$activationChallenge == null : this$activationChallenge.equals(other$activationChallenge)) {
               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;
            }
         } else {
            return false;
         }
      }
   }

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

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String toString() {
      return "StartDeviceActivationResult(activationSession="
         + this.getActivationSession()
         + ", activationChallenge="
         + this.getActivationChallenge()
         + ", failureReason="
         + this.getFailureReason()
         + ")";
   }

   @SuppressFBWarnings(justification = "generated code")
   private StartDeviceActivationResult(
      Optional<CrontoActivationSession> activationSession,
      Optional<CrontoDeviceActivationChallenge> activationChallenge,
      Optional<StartDeviceActivationResult.FailureReason> failureReason
   ) {
      this.activationSession = activationSession;
      this.activationChallenge = activationChallenge;
      this.failureReason = failureReason;
   }

   public enum FailureReason {
      CRONTO_OTP_WRONG,
      CRONTO_LETTER_INVALID,
      ILLEGAL_CRONTO_PLATFORM,
      CRONTO_DEVICE_LIMIT_REACHED,
      CRONTO_LETTER_USAGE_LIMIT_REACHED;
   }
}
