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

import com.airlock.iam.base.api.domain.model.validation.GenericError;
import com.airlock.iam.base.api.domain.model.validation.ValidationResult;
import com.airlock.iam.common.api.domain.model.locking.LockReason;
import com.airlock.iam.core.misc.authen.PredefinedLockReason;
import com.airlock.iam.core.misc.authen.TooManyAuthenticationAttemptsLockReason;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

public final class LockReasons {
   private final Set<LockReason> reasons;

   public LockReasons(Collection<String> reasons) {
      this.reasons = reasons.stream().map(LockReasons::toLockReason).collect(Collectors.toSet());
   }

   public boolean hasReason(LockReason reason) {
      return this.reasons.contains(reason);
   }

   public ValidationResult validate(LockReason reason) {
      ValidationResult validation = ValidationResult.valid();
      if (!this.hasReason(reason)) {
         validation.mergeWith(ValidationResult.singleError("reason", GenericError.INVALID_VALUE));
      }

      return validation;
   }

   public static LockReason toLockReason(String reason) {
      return Arrays.stream(PredefinedLockReason.values())
         .map(LockReason.class::cast)
         .filter(r -> r.getResourceKey().equals(reason))
         .findFirst()
         .or(() -> TooManyAuthenticationAttemptsLockReason.createForLockReason(reason))
         .orElse(LockReasonImpl.lockReason(reason));
   }
}
