package com.airlock.iam.flow.shared.domain.model.condition;

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.common.api.domain.model.user.User;
import com.airlock.iam.common.api.domain.model.valueprovider.ValueProvider;
import com.airlock.iam.common.domain.service.user.StringValueUniquenessService;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.flow.api.domain.model.step.FlowCondition;
import com.airlock.iam.flow.shared.application.configuration.condition.UserAttributeUniquenessConditionConfig;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Optional;

@LogicForConfig(UserAttributeUniquenessConditionConfig.class)
public class UserAttributeUniquenessCondition implements FlowCondition {
   private static final ELogger LOG = ELoggerFactory.getLogger(UserAttributeUniquenessCondition.class);
   private final StringValueUniquenessService uniquenessService;
   private final String userAttributeName;
   private final ValueProvider<String> attributeValueProvider;
   private final Provider<User> user;

   @Inject
   public UserAttributeUniquenessCondition(
      UserAttributeUniquenessConditionConfig config, ValueProvider<String> attributeValue, StringValueUniquenessService uniquenessService, Provider<User> user
   ) {
      this.uniquenessService = uniquenessService;
      this.user = user;
      this.userAttributeName = config.getUserAttribute().getContextDataName();
      this.attributeValueProvider = attributeValue;
   }

   @Override
   public boolean isFulfilled() {
      String attributeValue = this.attributeValueProvider.getValue();
      String currentUserId = ((User)this.user.get()).getId().getValue();
      if (this.uniquenessService.attributeOfUserIsUnique(this.userAttributeName, attributeValue, Optional.of(currentUserId))) {
         LOG.debug(
            String.format(
               "Condition is fulfilled. No user exists with value \"%s\" for field \"%s\" and user ID different from  \"%s\".",
               attributeValue,
               this.userAttributeName,
               currentUserId
            )
         );
         return true;
      } else {
         LOG.debug(
            String.format(
               "Condition is not fulfilled. At least one user exists with value \"%s\" for field \"%s\" and user ID different from \"%s\".",
               attributeValue,
               this.userAttributeName,
               currentUserId
            )
         );
         return false;
      }
   }

   @Override
   public String displayName() {
      return "Context-Data " + LogUtil.quote(this.userAttributeName) + " Uniqueness";
   }
}
