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

import com.airlock.iam.common.api.domain.model.cronto.CrontoDeviceId;
import com.airlock.iam.core.domain.model.cronto.CrontoOtp;
import com.airlock.iam.core.misc.cronto.CrontoChallenge;
import com.airlock.iam.core.misc.impl.authen.CrontoUsedDeviceInfo;
import com.airlock.iam.core.misc.impl.authen.cronto.CrontoPushDeviceChoice;
import com.airlock.iam.core.misc.impl.cronto.CrontoChallengeResult;
import com.airlock.iam.core.misc.impl.token.cronto.CrontoDeviceToken;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import lombok.NonNull;

public interface CrontoCheckingService {
   CrontoCheckingService.CrontoInitCheckResult initiate(Optional<CrontoUsedDeviceInfo> var1);

   CrontoCheckingService.PushDeviceSelectionResult selectPushDevice(String var1);

   CrontoCheckingService.PushDeviceSelectionResult selectOffline();

   CrontoCheckingService.CrontoCheckResult checkOtp(CrontoOtp var1);

   CrontoCheckingService.CrontoCheckResult pollOnlineValidation();

   CrontoCheckingService.CrontoCheckResult cancelValidation();

   enum CheckFailureCode {
      PENDING(false),
      WRONG_RETRY(false),
      WRONG_NO_RETRY(true),
      DEVICE_BLOCKED(true),
      CANCELED(true);

      private final boolean finalResult;

      @SuppressFBWarnings(justification = "generated code")
      public boolean isFinalResult() {
         return this.finalResult;
      }

      @SuppressFBWarnings(justification = "generated code")
      CheckFailureCode(final boolean finalResult) {
         this.finalResult = finalResult;
      }
   }

   final class CrontoCheckResult {
      private final Optional<CrontoCheckingService.CheckFailureCode> failure;
      private final CrontoChallengeResult.CrontoMethod usedMethod;
      private final Optional<CrontoDeviceId> usedDevice;

      public static CrontoCheckingService.CrontoCheckResult checkSuccess(@NonNull CrontoDeviceId deviceId, @NonNull CrontoChallengeResult.CrontoMethod method) {
         if (deviceId == null) {
            throw new NullPointerException("deviceId is marked non-null but is null");
         } else if (method == null) {
            throw new NullPointerException("method is marked non-null but is null");
         } else {
            return new CrontoCheckingService.CrontoCheckResult(Optional.empty(), method, Optional.of(deviceId));
         }
      }

      public static CrontoCheckingService.CrontoCheckResult checkFailure(
         @NonNull CrontoCheckingService.CheckFailureCode failure, @NonNull CrontoChallengeResult.CrontoMethod method
      ) {
         if (failure == null) {
            throw new NullPointerException("failure is marked non-null but is null");
         } else if (method == null) {
            throw new NullPointerException("method is marked non-null but is null");
         } else {
            return new CrontoCheckingService.CrontoCheckResult(Optional.of(failure), method, Optional.empty());
         }
      }

      public boolean isSuccess() {
         return this.failure.isEmpty();
      }

      public boolean isFinalResult() {
         return this.failure.isEmpty() || this.failure.get().isFinalResult();
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<CrontoCheckingService.CheckFailureCode> getFailure() {
         return this.failure;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoChallengeResult.CrontoMethod getUsedMethod() {
         return this.usedMethod;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<CrontoDeviceId> getUsedDevice() {
         return this.usedDevice;
      }

      @SuppressFBWarnings(justification = "generated code")
      private CrontoCheckResult(
         Optional<CrontoCheckingService.CheckFailureCode> failure, CrontoChallengeResult.CrontoMethod usedMethod, Optional<CrontoDeviceId> usedDevice
      ) {
         this.failure = failure;
         this.usedMethod = usedMethod;
         this.usedDevice = usedDevice;
      }
   }

   final class CrontoInitCheckResult {
      private final Optional<CrontoCheckingService.InitFailureCode> failure;
      private final Optional<CrontoCheckingService.CrontoServiceChallenge> challenge;
      private final List<CrontoPushDeviceChoice> deviceChoices;

      public static CrontoCheckingService.CrontoInitCheckResult initFailure(@NonNull CrontoCheckingService.InitFailureCode code) {
         if (code == null) {
            throw new NullPointerException("code is marked non-null but is null");
         } else {
            return new CrontoCheckingService.CrontoInitCheckResult(Optional.of(code), Optional.empty(), Collections.emptyList());
         }
      }

      public static CrontoCheckingService.CrontoInitCheckResult initChallenge(@NonNull CrontoCheckingService.CrontoServiceChallenge challenge) {
         if (challenge == null) {
            throw new NullPointerException("challenge is marked non-null but is null");
         } else {
            return new CrontoCheckingService.CrontoInitCheckResult(Optional.empty(), Optional.of(challenge), Collections.emptyList());
         }
      }

      public static CrontoCheckingService.CrontoInitCheckResult initSelection(@NonNull List<CrontoPushDeviceChoice> choices) {
         if (choices == null) {
            throw new NullPointerException("choices is marked non-null but is null");
         } else {
            return new CrontoCheckingService.CrontoInitCheckResult(Optional.empty(), Optional.empty(), choices);
         }
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<CrontoCheckingService.InitFailureCode> getFailure() {
         return this.failure;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<CrontoCheckingService.CrontoServiceChallenge> getChallenge() {
         return this.challenge;
      }

      @SuppressFBWarnings(justification = "generated code")
      public List<CrontoPushDeviceChoice> getDeviceChoices() {
         return this.deviceChoices;
      }

      @SuppressFBWarnings(justification = "generated code")
      private CrontoInitCheckResult(
         Optional<CrontoCheckingService.InitFailureCode> failure,
         Optional<CrontoCheckingService.CrontoServiceChallenge> challenge,
         List<CrontoPushDeviceChoice> deviceChoices
      ) {
         this.failure = failure;
         this.challenge = challenge;
         this.deviceChoices = deviceChoices;
      }
   }

   final class CrontoServiceChallenge {
      private final CrontoChallenge challenge;
      private final Optional<CrontoChallengeResult.CrontoMethod> method;
      private final List<CrontoDeviceToken> pushDevices;
      private final Optional<String> pushLoginId;

      public boolean isPushChallenge() {
         return this.method.isPresent() && CrontoChallengeResult.CrontoMethod.PUSH == this.method.get() && !this.pushDevices.isEmpty();
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoServiceChallenge(
         CrontoChallenge challenge, Optional<CrontoChallengeResult.CrontoMethod> method, List<CrontoDeviceToken> pushDevices, Optional<String> pushLoginId
      ) {
         this.challenge = challenge;
         this.method = method;
         this.pushDevices = pushDevices;
         this.pushLoginId = pushLoginId;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoChallenge getChallenge() {
         return this.challenge;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<CrontoChallengeResult.CrontoMethod> getMethod() {
         return this.method;
      }

      @SuppressFBWarnings(justification = "generated code")
      public List<CrontoDeviceToken> getPushDevices() {
         return this.pushDevices;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<String> getPushLoginId() {
         return this.pushLoginId;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         if (o == this) {
            return true;
         } else if (!(o instanceof CrontoCheckingService.CrontoServiceChallenge other)) {
            return false;
         } else {
            Object this$challenge = this.challenge;
            Object other$challenge = other.challenge;
            if (this$challenge == null ? other$challenge == null : this$challenge.equals(other$challenge)) {
               Object this$method = this.method;
               Object other$method = other.method;
               if (this$method == null ? other$method == null : this$method.equals(other$method)) {
                  Object this$pushDevices = this.pushDevices;
                  Object other$pushDevices = other.pushDevices;
                  if (this$pushDevices == null ? other$pushDevices == null : this$pushDevices.equals(other$pushDevices)) {
                     Object this$pushLoginId = this.pushLoginId;
                     Object other$pushLoginId = other.pushLoginId;
                     return this$pushLoginId == null ? other$pushLoginId == null : this$pushLoginId.equals(other$pushLoginId);
                  } else {
                     return false;
                  }
               } else {
                  return false;
               }
            } else {
               return false;
            }
         }
      }

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

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "CrontoCheckingService.CrontoServiceChallenge(challenge="
            + this.getChallenge()
            + ", method="
            + this.getMethod()
            + ", pushDevices="
            + this.getPushDevices()
            + ", pushLoginId="
            + this.getPushLoginId()
            + ")";
      }
   }

   enum InitFailureCode {
      ACTIVATION_REQUIRED,
      NO_PUSH_DEVICE,
      NO_ACTIVE_DEVICE;
   }

   final class PushDeviceSelectionResult {
      private final Optional<CrontoCheckingService.CrontoServiceChallenge> challenge;
      private final List<CrontoPushDeviceChoice> deviceChoices;

      public static CrontoCheckingService.PushDeviceSelectionResult selectionSuccess(@NonNull CrontoCheckingService.CrontoServiceChallenge challenge) {
         if (challenge == null) {
            throw new NullPointerException("challenge is marked non-null but is null");
         } else {
            return new CrontoCheckingService.PushDeviceSelectionResult(Optional.of(challenge), Collections.emptyList());
         }
      }

      public static CrontoCheckingService.PushDeviceSelectionResult selectionFailure(@NonNull List<CrontoPushDeviceChoice> choices) {
         if (choices == null) {
            throw new NullPointerException("choices is marked non-null but is null");
         } else {
            return new CrontoCheckingService.PushDeviceSelectionResult(Optional.empty(), choices);
         }
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<CrontoCheckingService.CrontoServiceChallenge> getChallenge() {
         return this.challenge;
      }

      @SuppressFBWarnings(justification = "generated code")
      public List<CrontoPushDeviceChoice> getDeviceChoices() {
         return this.deviceChoices;
      }

      @SuppressFBWarnings(justification = "generated code")
      private PushDeviceSelectionResult(Optional<CrontoCheckingService.CrontoServiceChallenge> challenge, List<CrontoPushDeviceChoice> deviceChoices) {
         this.challenge = challenge;
         this.deviceChoices = deviceChoices;
      }
   }
}
