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

import com.airlock.iam.admin.domain.model.token.TokenController;
import com.airlock.iam.common.api.domain.model.user.PersistentUser;
import com.airlock.iam.common.application.configuration.userprofile.UserProfileItemConfig;
import com.airlock.iam.core.misc.persistency.UserGroupCondition;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.license.PluginPropertyLicenseRestriction;
import com.airlock.iam.plugin.api.annotation.property.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import com.airlock.iam.plugin.api.annotation.property.StringListProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.List;
import java.util.Objects;

@Plugin(description = "Defines user-group dependent user settings for the admin tool.")
public class UserGroupConfiguration {
   @PluginProperty(description = "The group condition selecting this admin tool settings for a user.", optional = false)
   private UserGroupCondition groupCondition;
   @PluginListProperty(
      description = "List of authentication tokens that can be managed in the Adminapp.",
      displayName = "Authentication Tokens (Credentials)",
      optional = true,
      minElements = 1
   )
   private List<TokenController> authenticationTokens;
   @BooleanProperty(
      description = "If this property is set to \"true\", user data is editable and users can be deleted.",
      optional = true,
      defaultValue = "true"
   )
   private boolean editable;
   @BooleanProperty(
      description = "If this property is set to \"true\", a section with the user valid status, valid-from and valid-to dates (if information is available) is displayed. On the user edit page, the valid-from and valid-to dates can be edited.",
      optional = true,
      defaultValue = "false"
   )
   private boolean showUserValidSection;
   @StringListProperty(description = "Set of roles assignable to users.", exampleElements = {"employee", "customer"}, optional = true)
   private List<String> availableUserRoles;
   @PluginListProperty(
      description = "The property names and labels of context data to be displayed on the user detail page.<p>The data is taken from the context data container of the selected user. <b>The configuration of the used user persister must include the context data properties referenced here.</b>",
      optional = true
   )
   private List<UserProfileItemConfig> rowsOnUserDetailPage;
   @PluginProperty(description = "Configures the behavior of user locking.", optional = false)
   private LockingSettings lockingSettings;
   @BooleanProperty(
      description = "If enabled, the credential migration section is be displayed on the user details page. This section contains a choice of authentication methods to be assigned to the user after migration.",
      optional = true,
      defaultValue = "false"
   )
   @PluginPropertyLicenseRestriction(moduleAffiliation = "TokenSelfService")
   private boolean showCredentialMigrationSection;

   boolean useForUser(PersistentUser user) {
      Objects.requireNonNull(user);
      return this.groupCondition.isUserMemberOfGroup(user);
   }

   public List<TokenController> getAuthenticationTokens() {
      return this.authenticationTokens;
   }

   public boolean isEditable() {
      return this.editable;
   }

   public boolean isShowUserValidSection() {
      return this.showUserValidSection;
   }

   public List<String> getAvailableUserRoles() {
      return this.availableUserRoles;
   }

   public List<UserProfileItemConfig> getRowsOnUserDetailPage() {
      return this.rowsOnUserDetailPage;
   }

   public LockingSettings getLockingSettings() {
      return this.lockingSettings;
   }

   public boolean isShowCredentialMigrationSection() {
      return this.showCredentialMigrationSection;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public UserGroupConfiguration(
      UserGroupCondition groupCondition,
      List<TokenController> authenticationTokens,
      boolean editable,
      boolean showUserValidSection,
      List<String> availableUserRoles,
      List<UserProfileItemConfig> rowsOnUserDetailPage,
      LockingSettings lockingSettings,
      boolean showCredentialMigrationSection
   ) {
      this.groupCondition = groupCondition;
      this.authenticationTokens = authenticationTokens;
      this.editable = editable;
      this.showUserValidSection = showUserValidSection;
      this.availableUserRoles = availableUserRoles;
      this.rowsOnUserDetailPage = rowsOnUserDetailPage;
      this.lockingSettings = lockingSettings;
      this.showCredentialMigrationSection = showCredentialMigrationSection;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class UserGroupConfigurationBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private UserGroupCondition groupCondition;
      @SuppressFBWarnings(justification = "generated code")
      private List<TokenController> authenticationTokens;
      @SuppressFBWarnings(justification = "generated code")
      private boolean editable;
      @SuppressFBWarnings(justification = "generated code")
      private boolean showUserValidSection;
      @SuppressFBWarnings(justification = "generated code")
      private List<String> availableUserRoles;
      @SuppressFBWarnings(justification = "generated code")
      private List<UserProfileItemConfig> rowsOnUserDetailPage;
      @SuppressFBWarnings(justification = "generated code")
      private LockingSettings lockingSettings;
      @SuppressFBWarnings(justification = "generated code")
      private boolean showCredentialMigrationSection;

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

      @SuppressFBWarnings(justification = "generated code")
      public UserGroupConfiguration.UserGroupConfigurationBuilder groupCondition(UserGroupCondition groupCondition) {
         this.groupCondition = groupCondition;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserGroupConfiguration.UserGroupConfigurationBuilder authenticationTokens(List<TokenController> authenticationTokens) {
         this.authenticationTokens = authenticationTokens;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserGroupConfiguration.UserGroupConfigurationBuilder editable(boolean editable) {
         this.editable = editable;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserGroupConfiguration.UserGroupConfigurationBuilder showUserValidSection(boolean showUserValidSection) {
         this.showUserValidSection = showUserValidSection;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserGroupConfiguration.UserGroupConfigurationBuilder availableUserRoles(List<String> availableUserRoles) {
         this.availableUserRoles = availableUserRoles;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserGroupConfiguration.UserGroupConfigurationBuilder rowsOnUserDetailPage(List<UserProfileItemConfig> rowsOnUserDetailPage) {
         this.rowsOnUserDetailPage = rowsOnUserDetailPage;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserGroupConfiguration.UserGroupConfigurationBuilder lockingSettings(LockingSettings lockingSettings) {
         this.lockingSettings = lockingSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserGroupConfiguration.UserGroupConfigurationBuilder showCredentialMigrationSection(boolean showCredentialMigrationSection) {
         this.showCredentialMigrationSection = showCredentialMigrationSection;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserGroupConfiguration build() {
         return new UserGroupConfiguration(
            this.groupCondition,
            this.authenticationTokens,
            this.editable,
            this.showUserValidSection,
            this.availableUserRoles,
            this.rowsOnUserDetailPage,
            this.lockingSettings,
            this.showCredentialMigrationSection
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "UserGroupConfiguration.UserGroupConfigurationBuilder(groupCondition="
            + this.groupCondition
            + ", authenticationTokens="
            + this.authenticationTokens
            + ", editable="
            + this.editable
            + ", showUserValidSection="
            + this.showUserValidSection
            + ", availableUserRoles="
            + this.availableUserRoles
            + ", rowsOnUserDetailPage="
            + this.rowsOnUserDetailPage
            + ", lockingSettings="
            + this.lockingSettings
            + ", showCredentialMigrationSection="
            + this.showCredentialMigrationSection
            + ")";
      }
   }
}
