package com.airlock.iam.plugin.configeditor.ui;

import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.plugin.configeditor.data.ConfigContainer;
import com.airlock.iam.plugin.framework.application.service.ConfigWriter;
import com.airlock.iam.plugin.framework.application.service.TranslationFilter;
import com.airlock.iam.system.config.ConfigFormat;
import com.airlock.iam.system.property.IamSystemProperties;
import com.vaadin.server.ConnectorResource;
import com.vaadin.server.DownloadStream;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.function.Supplier;

public class DownloadConfigurationResource implements ConnectorResource {
   private static final ELogger LOG = ELoggerFactory.getLogger(DownloadConfigurationResource.class);
   private final Supplier<ConfigContainer> configFileHandler;
   private final Supplier<TranslationFilter> translationFilters;

   public DownloadConfigurationResource(Supplier<ConfigContainer> configFileHandler, Supplier<TranslationFilter> translationFilters) {
      this.configFileHandler = configFileHandler;
      this.translationFilters = translationFilters;
   }

   public DownloadStream getStream() {
      LOG.debug("getStream() - downloading current config.");
      return this.getConfigFileDownloadStream();
   }

   private DownloadStream getConfigFileDownloadStream() {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      this.saveCurrentConfigFile(bos);
      byte[] memCfg = this.getConfigFromStream(bos);
      return this.getDownloadStream(memCfg);
   }

   private void saveCurrentConfigFile(ByteArrayOutputStream bos) {
      try {
         this.configFileHandler
            .get()
            .saveConfiguration(this.useYaml() ? ConfigFormat.YAML_FORMAT : ConfigFormat.XML_FORMAT, bos, this.translationFilters.get());
      } catch (ConfigWriter.ConfigWriterException e) {
         throw new IllegalArgumentException("Configuration exception.", e);
      }
   }

   private byte[] getConfigFromStream(ByteArrayOutputStream bos) {
      return bos.toByteArray();
   }

   private DownloadStream getDownloadStream(byte[] memCfg) {
      String configFileName = this.getFilename();
      DownloadStream ds = new DownloadStream(new ByteArrayInputStream(memCfg), this.getMIMEType(), configFileName);
      ds.setCacheTime(0L);
      ds.setParameter("Content-Disposition", "attachment; filename=" + configFileName);
      return ds;
   }

   public String getFilename() {
      if (this.configFileHandler.get().getDictionary().isDocumentTypeSnippet()) {
         return "iam-config-snippet.yaml";
      } else {
         return IamSystemProperties.isYAMLConfigFormatEnabled() ? "iam-config.yaml" : "medusa-configuration.xml";
      }
   }

   @SuppressFBWarnings("NM_CONFUSING")
   public String getMIMEType() {
      return this.useYaml() ? "application/yaml" : "text/xml";
   }

   private boolean useYaml() {
      boolean isSnippet = this.configFileHandler.get().getDictionary().isDocumentTypeSnippet();
      return IamSystemProperties.isYAMLConfigFormatEnabled() || isSnippet;
   }
}
