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

import com.airlock.iam.plugin.framework.application.service.ConfigWriter;
import com.airlock.iam.plugin.framework.domain.model.MedusaConfigurationElement;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.XStreamException;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;

public class XStreamConfigWriter implements ConfigWriter {
   private final XStream xStream;

   public XStreamConfigWriter(XStream xStream) {
      this.xStream = xStream;
   }

   @Override
   public void write(MedusaConfigurationElement config, OutputStream out) throws ConfigWriter.ConfigWriterException {
      try (OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
         this.write(config, writer);
      } catch (IOException e) {
         throw new ConfigWriter.ConfigWriterException("Cannot write config: " + e.getMessage(), e);
      }
   }

   private void write(MedusaConfigurationElement configToWrite, Writer writer) throws ConfigWriter.ConfigWriterException {
      PrettyPrintWriter xwriter = new PrettyPrintWriter(writer);

      try {
         writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
         this.xStream.marshal(configToWrite, xwriter);
         writer.write(10);
      } catch (XStreamException e) {
         throw new ConfigWriter.ConfigWriterException("Failed to write XML configuration: " + e.getMessage(), e);
      } catch (IOException e) {
         throw new ConfigWriter.ConfigWriterException("Unable to write config: " + e.getMessage(), e);
      } finally {
         xwriter.close();
      }
   }
}
