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

import com.airlock.iam.base.misc.io.Files;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.exception.InitializeException;
import com.airlock.iam.plugin.framework.application.service.ConfigWriter;
import com.airlock.iam.plugin.framework.misc.PluginFramework;
import com.airlock.iam.plugin.framework.misc.config.PluginConfigurationDictionary;
import com.airlock.iam.plugin.framework.misc.frompersistence.TranslatedMedusaConfiguration;
import com.airlock.iam.sensitivevalues.application.service.SensitiveValuesProvider;
import com.airlock.iam.system.config.ConfigFormat;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.Optional;
import java.util.function.Supplier;

public class PluginConfigurationDictionaryUtils {
   public static void atomicWriteDictionaryToFile(PluginConfigurationDictionary dictionary, ConfigFormat configFormat, Path outputFile) {
      try {
         Files.doAtomicallyViaSiblingTempFile(outputFile, tempFile -> writeDictionary(dictionary, configFormat, tempFile));
      } catch (IOException e) {
         throw new ConfigPersistenceException(
            "Unable to write the configuration file: " + outputFile + ". Could not process temporary file: " + e.getMessage(), e
         );
      }
   }

   private static void writeDictionary(PluginConfigurationDictionary dictionary, ConfigFormat configFormat, Path path) {
      try (OutputStream outputStream = java.nio.file.Files.newOutputStream(path)) {
         PluginFramework.getTranslatedConfigWriter(configFormat).writeConfig(dictionary.toTranslatedConfiguration(), outputStream);
      } catch (IOException | ConfigWriter.ConfigWriterException e) {
         throw new ConfigPersistenceException("Unable to write the configuration to file: " + path + ", reason: " + e.getMessage(), e);
      }
   }

   public static PluginConfigurationDictionary loadDictionaryFromFile(
      Path path, ConfigFormat configFormat, Supplier<Optional<SensitiveValuesProvider>> sensitiveValuesProvider, Supplier<ConfigurationEnvironment> env
   ) {
      try {
         TranslatedMedusaConfiguration config = PluginFramework.getTranslatedConfigReader(configFormat).loadConfig(path.toFile());
         return PluginConfigurationDictionary.fromTranslatedConfiguration(config, sensitiveValuesProvider, env);
      } catch (InitializeException e) {
         throw new ConfigPersistenceException("Unable to load the configuration from file: " + path + ", reason: " + e.getMessage(), e);
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   private PluginConfigurationDictionaryUtils() {
   }
}
