package com.airlock.iam.common.domain.model.otp;

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.base.misc.time.TimeProvider;
import com.airlock.iam.common.api.domain.model.otp.OneTimePassword;
import com.airlock.iam.common.api.domain.model.otp.Otp;
import com.airlock.iam.common.api.domain.model.otp.OtpEqualityStrategy;
import com.airlock.iam.common.api.domain.model.otp.UnverifiedOtp;
import com.google.common.annotations.VisibleForTesting;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.time.Duration;

public final class SimulatedExpiringOneTimePassword implements OneTimePassword {
   @VisibleForTesting
   static final Otp SIMULATED_OTP = Otp.otp("simulated");
   private final OneTimePassword invalidOneTimePassword;

   SimulatedExpiringOneTimePassword(Duration validity, TimeProvider timeProvider) {
      this.invalidOneTimePassword = new ExpiringOneTimePassword(SIMULATED_OTP, validity, timeProvider);
   }

   @Override
   public OneTimePassword.OneTimeCodeVerificationResult verify(UnverifiedOtp otherValue, OtpEqualityStrategy strategy) {
      return switch (this.invalidOneTimePassword.verify(otherValue, strategy)) {
         case EXPIRED -> OneTimePassword.OneTimeCodeVerificationResult.EXPIRED;
         case SUCCESS, WRONG_VALUE -> OneTimePassword.OneTimeCodeVerificationResult.WRONG_VALUE;
      };
   }

   public SimulatedExpiringOneTimePassword renewValidity() {
      return new SimulatedExpiringOneTimePassword(this.invalidOneTimePassword.renewValidity());
   }

   @Override
   public Otp value() {
      throw new FailureException("A simulated expiring one-time code does not have any value!");
   }

   @SuppressFBWarnings(justification = "generated code")
   public SimulatedExpiringOneTimePassword(OneTimePassword invalidOneTimePassword) {
      this.invalidOneTimePassword = invalidOneTimePassword;
   }

   @SuppressFBWarnings(justification = "generated code")
   public OneTimePassword getInvalidOneTimePassword() {
      return this.invalidOneTimePassword;
   }
}
