package com.airlock.iam.admin.application.configuration.generic.ui;

import com.airlock.iam.plugin.api.annotation.config.Groups;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.GroupProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

@Plugin(
   description = "A configurable UI to manage tokens that are provided by the IAM REST generic token endpoints.\nThe controller is displayed as separate tab on the user management tab sheet of the Adminapp.",
   displayName = "Generic Token Controller UI"
)
@Groups(
   groupSequence = {"Basic Settings", "Token Actions Visibility", "Activation Order Visibility"},
   openGroups = {"Basic Settings", "Token Actions Visibility", "Activation Order Visibility"}
)
public final class GenericTokenControllerUiConfig {
   private static final String ACTIONS_VISIBILITY_HINT = "<p>The visibility of the button depends on the configured access control and if the\nadministrator has permission for this action.</p>";
   static final String TOKEN_ACTIONS_GROUP = "Token Actions Visibility";
   static final String ACTIVATION_ORDER_GROUP = "Activation Order Visibility";
   @PluginListProperty(
      description = "Defines the visible UI elements of this token controller.",
      displayName = "UI Elements",
      minElements = 1,
      optional = false
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private List<TokenControllerUiElementConfig> uiElements;
   @BooleanProperty(
      description = "If enabled, displays an \"Add\" button that creates an empty and unsaved client-side token. The button is visible as long as the server allows to create more tokens and the maximum token count is not reached.<p>The visibility of the button depends on the configured access control and if the\nadministrator has permission for this action.</p>",
      optional = true,
      defaultValue = "true"
   )
   @GroupProperty(groupIdentifier = "Token Actions Visibility")
   private boolean showAddButton;
   @BooleanProperty(
      description = "If enabled, a \"Save\" button is displayed that allows the admin to submit changed token data to the server. For new tokens, the \"Save\" button is always shown.<p>The visibility of the button depends on the configured access control and if the\nadministrator has permission for this action.</p>",
      optional = true,
      defaultValue = "true"
   )
   @GroupProperty(groupIdentifier = "Token Actions Visibility")
   private boolean showSaveButton;
   @BooleanProperty(
      description = "If enabled, displays a \"Delete\" button that will remove the token from the user on the server. <p>The visibility of the button depends on the configured access control and if the\nadministrator has permission for this action.</p>",
      optional = true,
      defaultValue = "true"
   )
   @GroupProperty(groupIdentifier = "Token Actions Visibility")
   private boolean showDeleteButton;
   @BooleanProperty(
      description = "If enabled, displays either an \"Enable\" or \"Disable\" button to change the state of this token on the server. The button is only visible if the \"Enabled\" property is mapped in the \"Token Endpoint\" settings of this controller. The \"Identity Attribute Mapping\" is not supported.<p>The visibility of the button depends on the configured access control and if the\nadministrator has permission for this action.</p>",
      displayName = "Show Enable/Disable Button",
      optional = true,
      defaultValue = "true"
   )
   @GroupProperty(groupIdentifier = "Token Actions Visibility")
   private boolean showEnableDisableButton;
   @BooleanProperty(
      description = "If enabled, displays a section to view and manage activation orders. Managing orders also depends on \"Show Order/Cancel Button\".",
      optional = true,
      displayName = "Show Activation Order",
      defaultValue = "true"
   )
   @GroupProperty(groupIdentifier = "Activation Order Visibility")
   private boolean showActivationOrder;
   private static final String SHOW_ACTIVATION_ORDER_DISPLAY_NAME = "Show Activation Order";
   @BooleanProperty(
      description = "If enabled, displays either an \"Order\" or \"Cancel\" button to manage activation letters. This option is only visible if \"Show Activation Order\" is enabled.<p>The visibility of the button depends on the configured access control and if the\nadministrator has permission for this action.</p>",
      displayName = "Show Order/Cancel Button",
      optional = true,
      defaultValue = "true"
   )
   @GroupProperty(groupIdentifier = "Activation Order Visibility")
   private boolean showOrderCancelButton;
   private static final String ORDER_CANCEL_LETTER_DISPLAY_NAME = "Show Order/Cancel Button";

   public List<TokenControllerUiElementConfig> getUiElements() {
      return this.uiElements;
   }

   public boolean isShowAddButton() {
      return this.showAddButton;
   }

   public boolean isShowSaveButton() {
      return this.showSaveButton;
   }

   public boolean isShowDeleteButton() {
      return this.showDeleteButton;
   }

   public boolean isShowEnableDisableButton() {
      return this.showEnableDisableButton;
   }

   public boolean isShowActivationOrder() {
      return this.showActivationOrder;
   }

   public boolean isShowOrderCancelButton() {
      return this.showOrderCancelButton;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public GenericTokenControllerUiConfig(
      List<TokenControllerUiElementConfig> uiElements,
      boolean showAddButton,
      boolean showSaveButton,
      boolean showDeleteButton,
      boolean showEnableDisableButton,
      boolean showActivationOrder,
      boolean showOrderCancelButton
   ) {
      this.uiElements = uiElements;
      this.showAddButton = showAddButton;
      this.showSaveButton = showSaveButton;
      this.showDeleteButton = showDeleteButton;
      this.showEnableDisableButton = showEnableDisableButton;
      this.showActivationOrder = showActivationOrder;
      this.showOrderCancelButton = showOrderCancelButton;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class GenericTokenControllerUiConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<TokenControllerUiElementConfig> uiElements;
      @SuppressFBWarnings(justification = "generated code")
      private boolean showAddButton;
      @SuppressFBWarnings(justification = "generated code")
      private boolean showSaveButton;
      @SuppressFBWarnings(justification = "generated code")
      private boolean showDeleteButton;
      @SuppressFBWarnings(justification = "generated code")
      private boolean showEnableDisableButton;
      @SuppressFBWarnings(justification = "generated code")
      private boolean showActivationOrder;
      @SuppressFBWarnings(justification = "generated code")
      private boolean showOrderCancelButton;

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

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder uiElement(TokenControllerUiElementConfig uiElement) {
         if (this.uiElements == null) {
            this.uiElements = new ArrayList<>();
         }

         this.uiElements.add(uiElement);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder uiElements(Collection<? extends TokenControllerUiElementConfig> uiElements) {
         if (uiElements == null) {
            throw new NullPointerException("uiElements cannot be null");
         }

         if (this.uiElements == null) {
            this.uiElements = new ArrayList<>();
         }

         this.uiElements.addAll(uiElements);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder clearUiElements() {
         if (this.uiElements != null) {
            this.uiElements.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder showAddButton(boolean showAddButton) {
         this.showAddButton = showAddButton;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder showSaveButton(boolean showSaveButton) {
         this.showSaveButton = showSaveButton;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder showDeleteButton(boolean showDeleteButton) {
         this.showDeleteButton = showDeleteButton;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder showEnableDisableButton(boolean showEnableDisableButton) {
         this.showEnableDisableButton = showEnableDisableButton;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder showActivationOrder(boolean showActivationOrder) {
         this.showActivationOrder = showActivationOrder;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder showOrderCancelButton(boolean showOrderCancelButton) {
         this.showOrderCancelButton = showOrderCancelButton;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericTokenControllerUiConfig build() {
         return new GenericTokenControllerUiConfig(switch (this.uiElements == null ? 0 : this.uiElements.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.uiElements.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.uiElements));
         }, this.showAddButton, this.showSaveButton, this.showDeleteButton, this.showEnableDisableButton, this.showActivationOrder, this.showOrderCancelButton);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "GenericTokenControllerUiConfig.GenericTokenControllerUiConfigBuilder(uiElements="
            + this.uiElements
            + ", showAddButton="
            + this.showAddButton
            + ", showSaveButton="
            + this.showSaveButton
            + ", showDeleteButton="
            + this.showDeleteButton
            + ", showEnableDisableButton="
            + this.showEnableDisableButton
            + ", showActivationOrder="
            + this.showActivationOrder
            + ", showOrderCancelButton="
            + this.showOrderCancelButton
            + ")";
      }
   }
}
