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

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.ConfigurationException;
import com.airlock.iam.plugin.configeditor.ConfigEditorApplication;
import com.airlock.iam.plugin.configeditor.data.tree.PluginConfigurationTreeItem;
import com.airlock.iam.plugin.configeditor.util.GuiResources;
import com.airlock.iam.plugin.framework.application.service.license.LicenseManager;
import com.airlock.iam.plugin.framework.domain.model.verification.exception.PluginLicenseViolationException;
import com.airlock.iam.plugin.framework.domain.model.verification.exception.PluginPropertyLicenseViolationException;
import com.airlock.iam.plugin.framework.misc.config.PluginConfigurationPropertiesView;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.vaadin.server.ThemeResource;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ValidationStatusHandler {
   public ThemeResource getValidationStatusIconForPluginNode(PluginConfigurationTreeItem currentNode) {
      ThemeResource localValidationIcon = null;
      if (currentNode.hasErrors()) {
         localValidationIcon = GuiResources.ICON_VALIDATION_ERROR;
         if (containsLicenseViolationExceptions(currentNode.getErrors())) {
            localValidationIcon = GuiResources.ICON_VALIDATION_WARNING;
         }
      }

      return localValidationIcon;
   }

   public ThemeResource getParentValidationIcon(PluginConfigurationTreeItem currentNode, PluginConfigurationTreeItem parentNode) {
      return currentNode.hasErrors() && !parentNode.hasErrors() ? GuiResources.ICON_VALIDATION_WARNING : null;
   }

   public Set<ConfigurationException> collectLocalValidationErrors(
      PluginConfiguration pc,
      ConfigurationEnvironment environment,
      Map<PluginConfiguration, List<ConfigurationException>> validations,
      ConfigEditorApplication application
   ) {
      Set<ConfigurationException> localExceptions = new LinkedHashSet<>(validations.getOrDefault(pc, Collections.emptyList()));
      Collection<ConfigurationContext> configurationContexts = new PluginConfigurationPropertiesView(pc, environment)
         .inheritFromParent()
         .inheritFromCommonEnvironment()
         .getProperties()
         .getAllConfigurationContexts();
      LicenseManager licenseManager = application.getLicenseManager();

      for (ConfigurationContext context : configurationContexts) {
         List<ConfigurationException> exceptions = licenseManager.getConfigLicenseViolations(pc, environment, context);
         localExceptions.addAll(exceptions);
      }

      return localExceptions;
   }

   private static boolean containsLicenseViolationExceptions(Collection<ConfigurationException> localExceptions) {
      return !Collections2.filter(
            localExceptions,
            Predicates.or(Predicates.instanceOf(PluginLicenseViolationException.class), Predicates.instanceOf(PluginPropertyLicenseViolationException.class))
         )
         .isEmpty();
   }
}
