package com.airlock.iam.plugin.configeditor.ui.components;

import com.airlock.iam.configeditor.shared.application.ConfigEditorProperties;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.Environment;
import com.airlock.iam.plugin.api.exception.ConfigurationException;
import com.airlock.iam.plugin.configeditor.ConfigEditorApplication;
import com.airlock.iam.plugin.configeditor.data.EnvironmentSelection;
import com.airlock.iam.plugin.configeditor.ui.ConfigUtil;
import com.airlock.iam.plugin.configeditor.util.GuiResources;
import com.airlock.iam.plugin.configeditor.util.ValidationType;
import com.vaadin.event.LayoutEvents.LayoutClickListener;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.v7.shared.ui.combobox.FilteringMode;
import com.vaadin.v7.ui.ComboBox;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Set;

public class ValidationToolbar {
   private final ComboBox validationEnvironment;
   private final IconWithLabel validationGlobal;
   private final IconWithLabel validationSelection;
   private final HorizontalLayout layout = new HorizontalLayout();

   public ValidationToolbar(EnvironmentSelection configurationEnvironmentSelection, ConfigurationEnvironment instanceEnvironment) {
      this.layout.setWidth("100%");
      this.layout.addStyleName("toolbar-validation");
      this.layout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
      this.validationEnvironment = new ComboBox();
      this.validationEnvironment.setWidth("100%");
      this.validationEnvironment.setFilteringMode(FilteringMode.CONTAINS);
      this.validationEnvironment.setNullSelectionAllowed(false);
      this.validationEnvironment.addItem(ValidationType.NONE);
      this.validationEnvironment.addItem(ValidationType.DEFAULT);
      this.validationEnvironment.addItem(ValidationType.STRICT);
      ValidationType defaultValidationType;
      if (ConfigEditorProperties.configEditorProperties().getValidationDefault()) {
         defaultValidationType = ValidationType.STRICT;
      } else {
         defaultValidationType = ValidationType.NONE;
      }

      this.validationEnvironment.setValue(defaultValidationType);
      this.validationEnvironment.setImmediate(true);
      this.validationEnvironment.setBuffered(false);
      this.validationEnvironment.setTextInputAllowed(false);
      this.validationEnvironment.addValueChangeListener(event -> {
         this.getConfigEditorApplication().updateValidationState();
         this.getConfigEditorApplication().updateFormFields();
      });
      ValidationSelectionUpdater updater = new ValidationSelectionUpdater(this.validationEnvironment, instanceEnvironment, defaultValidationType);
      this.validationEnvironment
         .addValueChangeListener(
            event -> updater.saveCurrentValidationSelection(this.validationEnvironment, configurationEnvironmentSelection.getSelectedEnvironment())
         );
      configurationEnvironmentSelection.addListener(updater);
      VerticalLayout validationSelectorWithLabel = this.createValidationSelectorWithLabel(this.validationEnvironment);
      this.layout.addComponent(validationSelectorWithLabel);
      LayoutClickListener selectErrorPanelClickListener = event -> this.getConfigEditorApplication().selectErrorPanelInViewsTab();
      this.validationGlobal = new IconWithLabel(
         GuiResources.ICON_VALIDATION_OK, GuiResources.ICON_VALIDATION_DISABLED, "Overall", "Validate all plugins.", selectErrorPanelClickListener
      );
      this.validationGlobal.setId("validationGlobal");
      this.layout.addComponent(this.validationGlobal);
      this.validationSelection = new IconWithLabel(
         GuiResources.ICON_VALIDATION_OK, GuiResources.ICON_VALIDATION_DISABLED, "Plugin", "Validate the selected plugin.", selectErrorPanelClickListener
      );
      this.validationSelection.setId("validationSelection");
      this.layout.addComponent(this.validationSelection);
      this.layout.setExpandRatio(validationSelectorWithLabel, 2.0F);
      this.layout.setExpandRatio(this.validationGlobal, 1.0F);
      this.layout.setExpandRatio(this.validationSelection, 1.0F);
   }

   private ConfigEditorApplication getConfigEditorApplication() {
      return (ConfigEditorApplication)UI.getCurrent();
   }

   private VerticalLayout createValidationSelectorWithLabel(ComboBox comboBox) {
      VerticalLayout validationSelectLayout = new VerticalLayout();
      validationSelectLayout.setSpacing(false);
      validationSelectLayout.setMargin(false);
      validationSelectLayout.addStyleName("icon-with-label");
      validationSelectLayout.addStyleName("validation-select");
      Label validationCaption = new Label("Validation");
      validationSelectLayout.addComponent(comboBox);
      comboBox.setId("validationEnvironment");
      validationSelectLayout.addComponent(validationCaption);
      validationSelectLayout.setComponentAlignment(validationCaption, Alignment.BOTTOM_CENTER);
      return validationSelectLayout;
   }

   public void disableValidationIcons() {
      this.validationSelection.disable();
      this.validationGlobal.disable();
   }

   public boolean isValidationSelectionInErrorState() {
      return this.validationSelection.getIconImage() == GuiResources.ICON_VALIDATION_ERROR;
   }

   public boolean isValidationSelectionInSuccessfulState() {
      return this.validationSelection.getIconImage() == GuiResources.ICON_VALIDATION_OK;
   }

   public void setValidationSelectionSuccessful() {
      this.validationSelection.enable();
      this.validationSelection.setIconDescription("Validation successful.");
   }

   public void setValidationSelectionError(Set<ConfigurationException> exceptions) {
      this.validationSelection.enable();
      this.validationSelection.setIconImage(GuiResources.ICON_VALIDATION_ERROR);
      this.validationSelection.setIconDescription(ConfigUtil.renderExceptionListAsSimpleMessage(exceptions, true));
   }

   public void disableValidationSelectionIcon() {
      this.validationSelection.disable();
   }

   public void disableValidationGlobalIcon() {
      this.validationGlobal.disable();
   }

   public void setValidationGlobalSuccessful() {
      this.validationGlobal.enable();
      this.validationGlobal.setIconDescription("Validation successful.");
   }

   public void setValidationGlobalError(Set<ConfigurationException> exceptions) {
      this.validationGlobal.enable();
      this.validationGlobal.setIconImage(GuiResources.ICON_VALIDATION_ERROR);
      this.validationGlobal.setIconDescription(ConfigUtil.renderExceptionListAsSimpleMessage(exceptions, true));
   }

   public Environment getSelectedValidationEnvironment() {
      return ((ValidationType)this.validationEnvironment.getValue()).getValidationEnvironment();
   }

   @SuppressFBWarnings(justification = "generated code")
   public HorizontalLayout getLayout() {
      return this.layout;
   }
}
