package com.airlock.iam.authentication.application.configuration.targetapp;

import com.airlock.iam.authentication.application.configuration.rememberme.RememberMeTokenGeneratingStepConfig;
import com.airlock.iam.authentication.application.configuration.rememberme.RememberMeUserIdentifyingStepConfig;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.Environment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.ConfigurationException;
import com.airlock.iam.plugin.api.exception.PropertyConfigurationException;
import com.airlock.iam.plugin.framework.misc.config.validation.RecursivePluginValidator;
import com.airlock.iam.plugin.framework.misc.config.validation.RecursivePluginValidator.ValidatorArguments;
import java.util.Arrays;
import java.util.Optional;

public final class ValidateNoRememberMePlugins {
   private static final Class<?>[] REMEMBER_ME_STEP_CONFIGS = new Class[]{RememberMeTokenGeneratingStepConfig.class, RememberMeUserIdentifyingStepConfig.class};

   private ValidateNoRememberMePlugins() {
   }

   static void validateNoRememberMePlugins(PluginConfiguration pc, ConfigurationEnvironment env, ConfigurationContext context, Environment valEnv) throws ConfigurationException {
      new RecursivePluginValidator(pc, env, context, valEnv).validate(ValidateNoRememberMePlugins::validateNoRememberMePlugins);
   }

   private static Optional<PropertyConfigurationException> validateNoRememberMePlugins(ValidatorArguments arguments) {
      return pluginIsARememberMeStepConfig(arguments)
         ? Optional.of(
            new PropertyConfigurationException(
               arguments.parent(),
               arguments.env(),
               arguments.context(),
               "Plugins of type " + LogUtil.quote(arguments.pluginConfig().getPluginClassDisplayName()) + " require Remember-Me settings.",
               new String[]{arguments.propertyName()}
            )
         )
         : Optional.empty();
   }

   static boolean pluginIsARememberMeStepConfig(ValidatorArguments arguments) {
      return Arrays.stream(REMEMBER_ME_STEP_CONFIGS).map(Class::getName).anyMatch(c -> c.equals(arguments.pluginConfig().getPluginClassName()));
   }
}
