package com.airlock.iam.plugin.framework.infrastructure.io;

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.plugin.framework.application.service.ConfigWriter;
import com.airlock.iam.plugin.framework.domain.model.MedusaConfigurationElement;
import com.airlock.iam.plugin.framework.infrastructure.yaml.export.IamConfigurationRepresenter;
import com.airlock.iam.system.config.IamYamlSchema;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import org.snakeyaml.engine.v2.api.Dump;
import org.snakeyaml.engine.v2.api.DumpSettings;
import org.snakeyaml.engine.v2.api.YamlOutputStreamWriter;
import org.snakeyaml.engine.v2.common.FlowStyle;
import org.snakeyaml.engine.v2.exceptions.YamlEngineException;
import org.snakeyaml.engine.v2.nodes.Tag;

public class YamlConfigWriter implements ConfigWriter {
   private static final ELogger LOG = ELoggerFactory.getLogger(YamlConfigWriter.class);

   @Override
   public void write(MedusaConfigurationElement config, OutputStream out) throws ConfigWriter.ConfigWriterException {
      LOG.debug("Exporting configuration to YAML format.");
      DumpSettings dumpSettings = dumpSettings();

      try {
         YamlOutputStreamWriter writer = yamlOutputStreamWriter(out);

         try {
            Dump yamlWriter = new Dump(dumpSettings, new IamConfigurationRepresenter(dumpSettings, config));
            yamlWriter.dump(config, writer);
         } catch (Throwable var8) {
            if (writer != null) {
               try {
                  writer.close();
               } catch (Throwable var7) {
                  var8.addSuppressed(var7);
               }
            }

            throw var8;
         }

         if (writer != null) {
            writer.close();
         }
      } catch (IOException | YamlEngineException | FailureException e) {
         throw new ConfigWriter.ConfigWriterException("Failed to write plugin configuration file in YAML format: " + e.getMessage(), e);
      }
   }

   public static DumpSettings dumpSettings() {
      return DumpSettings.builder()
         .setDefaultFlowStyle(FlowStyle.BLOCK)
         .setExplicitRootTag(Optional.of(Tag.MAP))
         .setSplitLines(false)
         .setMaxSimpleKeyLength(1024)
         .setSchema(new IamYamlSchema())
         .build();
   }

   private static YamlOutputStreamWriter yamlOutputStreamWriter(OutputStream out) {
      return new YamlOutputStreamWriter(out, StandardCharsets.UTF_8) {
         public void processIOException(IOException e) {
            throw new FailureException(e);
         }
      };
   }
}
