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

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.common.api.domain.model.user.UserIdentity;
import com.airlock.iam.common.domain.model.user.PrincipalInfo;
import com.airlock.iam.flow.api.domain.model.step.FlowCondition;
import com.airlock.iam.flow.shared.application.configuration.newdevice.NewDeviceConditionConfig;
import com.airlock.iam.flow.shared.domain.model.newdevice.LoginFromNewDeviceKnownUsers;
import com.airlock.iam.flow.shared.domain.model.newdevice.LoginFromNewDeviceUserInfo;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Optional;

@LogicForConfig(NewDeviceConditionConfig.class)
public final class LoginFromNewDeviceCondition implements FlowCondition {
   private final Provider<PrincipalInfo> principalInfo;
   private final Provider<LoginFromNewDeviceKnownUsersReader> knownUsersReader;

   @Inject
   public LoginFromNewDeviceCondition(Provider<PrincipalInfo> principalInfo, Provider<LoginFromNewDeviceKnownUsersReader> knownUsersReader) {
      this.principalInfo = principalInfo;
      this.knownUsersReader = knownUsersReader;
   }

   @Override
   public boolean isFulfilled() {
      LoginFromNewDeviceKnownUsers knownUsers = ((LoginFromNewDeviceKnownUsersReader)this.knownUsersReader.get()).getValidKnownUsers();
      Optional<LoginFromNewDeviceUserInfo> previousLogin = knownUsers.findUser(this.userId());
      return previousLogin.isEmpty();
   }

   private UserId userId() {
      return ((PrincipalInfo)this.principalInfo.get())
         .getKnownIdentity()
         .map(UserIdentity::id)
         .orElseThrow(() -> new FailureException("User must be known for this condition."));
   }

   @Override
   public String displayName() {
      return "Logged in from a new device";
   }
}
