package com.airlock.iam.admin.application.configuration.users;

import com.airlock.iam.common.api.domain.model.store.user.UserStore;
import com.airlock.iam.core.application.configuration.store.user.DeletingUserStoreProvider;
import com.airlock.iam.core.application.configuration.store.user.InsertingUserStoreProvider;
import com.airlock.iam.core.application.configuration.store.user.UserStoreProvider;
import com.airlock.iam.core.application.configuration.store.user.UserStoreValidations;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.InitializeException;
import com.airlock.iam.plugin.api.valuereader.PluginPropertyValueReader;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

@Plugin(displayName = "User Store Configuration", description = "User repository configuration for the Adminapp using User Store implementations.")
public class UserStoreConfiguration extends UserRepositoryConfiguration {
   public static final String USER_STORE_CONFIGURATION_DISPLAY_NAME = "User Store Configuration";
   @PluginProperty(
      description = "User store for searching, loading, creating and updating users.",
      optional = false,
      globalPluginReference = "globalUserStore"
   )
   private UserStoreProvider userStore;
   private static final String USER_STORE_FIELD = "userStore";
   @PluginProperty(
      description = "User store to load user data for the user list page: Normally, user data is loaded using the user store defined in property \"User Store\". For an efficient user store this is unnecessary, but for a slow user store (e.g. one backed by a user persister) this property can speed up the user list page or user export. <br/>",
      displayName = "User List Detail Loader",
      optional = true
   )
   private UserStoreProvider userListDetailLoader;
   public static final String USER_LIST_DETAIL_LOADER_DISPLAY_NAME = "User List Detail Loader";

   @Override
   public UserStore getUserStore() {
      return this.userStore.getUserStore();
   }

   @Override
   public Optional<UserStore> getUserListDetailLoader() {
      return Optional.ofNullable(this.userListDetailLoader).map(UserStoreProvider::getUserStore);
   }

   public static boolean isInsertionAndDeletionUserStore(PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context) throws InitializeException {
      PluginConfiguration userStoreConfig = PluginPropertyValueReader.effectivePluginPropertyValue(config, "userStore", env, context);
      return UserStoreValidations.get().ensureStoreApi(userStoreConfig, new Class[]{InsertingUserStoreProvider.class, DeletingUserStoreProvider.class});
   }

   @SuppressFBWarnings(justification = "generated code")
   public static UserStoreConfiguration.UserStoreConfigurationBuilder builder() {
      return new UserStoreConfiguration.UserStoreConfigurationBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public UserStoreConfiguration() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public UserStoreConfiguration(UserStoreProvider userStore, UserStoreProvider userListDetailLoader) {
      this.userStore = userStore;
      this.userListDetailLoader = userListDetailLoader;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class UserStoreConfigurationBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private UserStoreProvider userStore;
      @SuppressFBWarnings(justification = "generated code")
      private UserStoreProvider userListDetailLoader;

      @SuppressFBWarnings(justification = "generated code")
      UserStoreConfigurationBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserStoreConfiguration.UserStoreConfigurationBuilder userStore(UserStoreProvider userStore) {
         this.userStore = userStore;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserStoreConfiguration.UserStoreConfigurationBuilder userListDetailLoader(UserStoreProvider userListDetailLoader) {
         this.userListDetailLoader = userListDetailLoader;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserStoreConfiguration build() {
         return new UserStoreConfiguration(this.userStore, this.userListDetailLoader);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "UserStoreConfiguration.UserStoreConfigurationBuilder(userStore="
            + this.userStore
            + ", userListDetailLoader="
            + this.userListDetailLoader
            + ")";
      }
   }
}
