package com.airlock.iam.common.domain.service.user;

import com.airlock.iam.base.api.domain.model.store.query.Restriction;
import com.airlock.iam.base.api.domain.model.store.query.StringField;
import com.airlock.iam.common.api.domain.model.store.user.UserStore;
import com.airlock.iam.common.api.domain.model.store.user.capability.UserStoreCapabilities;
import com.airlock.iam.common.api.domain.model.user.PersistentUser;
import com.google.common.collect.Lists;
import jakarta.inject.Inject;
import java.util.List;
import java.util.Optional;

public class StringValueUniquenessServiceImpl implements StringValueUniquenessService {
   private final UserStore userStore;

   @Inject
   public StringValueUniquenessServiceImpl(UserStore userStore) {
      this.userStore = userStore;
   }

   @Override
   public boolean attributeOfUserIsUnique(String attributeName, String attributeValue, Optional<String> excludedUserId) {
      Restriction hasConfiguredContextDataValue = this.userStore.schema().customFields().string(attributeName).equal(attributeValue);
      StringField<PersistentUser> userIdField = this.userStore.schema().identity();
      if (UserStoreCapabilities.COMPLEX_QUERIES.isSupportedBy(this.userStore)) {
         List<Restriction> restrictions = Lists.newArrayList(new Restriction[]{hasConfiguredContextDataValue});
         if (excludedUserId.isPresent()) {
            restrictions.add(userIdField.notEqual(excludedUserId.get()));
         }

         int usersWithSameAttributeValue = this.userStore.find().whereAllOf(restrictions).aggregate(this.userStore.schema().count());
         return usersWithSameAttributeValue == 0;
      } else {
         List<String> usersWithSameContextData = this.userStore.find().where(hasConfiguredContextDataValue).select(userIdField.selector()).list();
         return excludedUserId.isEmpty()
            ? usersWithSameContextData.isEmpty()
            : usersWithSameContextData.stream().allMatch(userId -> userId.equals(excludedUserId.get()));
      }
   }
}
