package com.airlock.iam.plugin.framework.misc.frompersistence;

import com.airlock.iam.plugin.framework.application.configuration.MutablePluginConfiguration;
import com.airlock.iam.plugin.framework.domain.model.Plugin;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Optional;

abstract class PluginRelationshipResolver {
   private final TranslationState translation;

   public PluginRelationshipResolver(TranslationState translation) {
      this.translation = (TranslationState)Preconditions.checkNotNull(translation);
   }

   protected final TranslationState getTranslationResult() {
      return this.translation;
   }

   public void resolve() throws PersistenceModelToPCModelTranslation.PersistenceModelToPCModelTranslationException {
      Map<String, Plugin> pluginsByID = Maps.newHashMap();
      this.addInstanceIds(pluginsByID);
      this.resolveInstanceConfigPlugins(pluginsByID);
   }

   private void addInstanceIds(Map<String, Plugin> pluginsByID) throws PersistenceModelToPCModelTranslation.PersistenceModelToPCModelTranslationException {
      for (Plugin plugin : this.translation.allPlugins()) {
         this.putMapWithKey(pluginsByID, this.determineIdentifier(plugin), plugin);
      }
   }

   protected abstract Optional<String> determineIdentifier(Plugin var1);

   private void putMapWithKey(Map<String, Plugin> map, Optional<String> key, Plugin value) throws PersistenceModelToPCModelTranslation.PersistenceModelToPCModelTranslationException {
      if (key.isPresent()) {
         this.putMapWithKey(map, key.get(), value);
      }
   }

   private void putMapWithKey(Map<String, Plugin> map, String key, Plugin value) throws PersistenceModelToPCModelTranslation.PersistenceModelToPCModelTranslationException {
      boolean keyExists = map.containsKey(key);
      if (keyExists && !this.duplicatesAllowed()) {
         throw this.newIdentifierNotUniqueException(key);
      }

      if (!keyExists || this.shouldOverwrite(key, value, map.get(key))) {
         map.put(key, value);
      }
   }

   protected boolean duplicatesAllowed() {
      return false;
   }

   protected boolean shouldOverwrite(String key, Plugin newValue, Plugin oldValue) {
      return true;
   }

   protected abstract PersistenceModelToPCModelTranslation.PersistenceModelToPCModelTranslationException newIdentifierNotUniqueException(String var1);

   private void resolveInstanceConfigPlugins(Map<String, Plugin> pluginsByID) throws PersistenceModelToPCModelTranslation.PluginReferenceCannotBeFollowed, PersistenceModelToPCModelTranslation.PersistenceModelToPCModelTranslationException {
      this.resolvePlugins(pluginsByID, this.translation.allPlugins());
   }

   private void resolvePlugins(Map<String, Plugin> pluginsByID, Iterable<Plugin> pluginsToResolve) throws PersistenceModelToPCModelTranslation.PluginReferenceCannotBeFollowed, PersistenceModelToPCModelTranslation.PersistenceModelToPCModelTranslationException {
      for (Plugin refereePlugin : pluginsToResolve) {
         if (this.needsToBeResolved(refereePlugin)) {
            MutablePluginConfiguration referee = this.translation.getPluginConfigurationFor(refereePlugin).get();
            Plugin referencedPlugin = this.lookupReferencedPlugin(pluginsByID, this.determineIDOfReferencedPlugin(refereePlugin));
            MutablePluginConfiguration referenced = this.translation.getPluginConfigurationFor(referencedPlugin).get();
            this.performAction(referee, refereePlugin, referenced);
         }
      }
   }

   protected abstract boolean needsToBeResolved(Plugin var1);

   protected abstract String determineIDOfReferencedPlugin(Plugin var1);

   private Plugin lookupReferencedPlugin(Map<String, Plugin> pluginsById, String referencedPluginID) throws PersistenceModelToPCModelTranslation.PluginReferenceCannotBeFollowed {
      Plugin template = pluginsById.get(referencedPluginID);
      if (template == null) {
         throw new PersistenceModelToPCModelTranslation.PluginReferenceCannotBeFollowed(referencedPluginID);
      } else {
         return template;
      }
   }

   protected abstract void performAction(MutablePluginConfiguration var1, Plugin var2, MutablePluginConfiguration var3) throws PersistenceModelToPCModelTranslation.PersistenceModelToPCModelTranslationException;
}
