package de.ivu.elect.was.exchange.wahl.wes;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.exchange.control.FileKonfiguration;
import de.ivu.elect.business.exchange.control.MappingException;
import de.ivu.elect.business.wahl.control.WahlExportObject;
import de.ivu.elect.business.wahl.control.WahlWesExportContext;

public class WahlFuerWesZipExportMapper extends AbstractWahlFuerWesExportMapper {

  private static final Logger LOG = LoggerFactory.getLogger(WahlFuerWesZipExportMapper.class);

  private static final int BUFFER_SIZE = 100 * 1024;

  private static final int COPY_BUFFER = 64 * 1024;

  @Override
  public void serialize(List<WahlExportObject> object, OutputStream os, WahlWesExportContext context, FileKonfiguration fileKonfiguration) throws MappingException {
    Map<String, byte[]> map = mappeWahlen(object, context);
    if (map.isEmpty()) {
      return;
    }

    try (ZipOutputStream zos = new ZipOutputStream(os)) {
      zos.putNextEntry(new ZipEntry(WAHL_DIR + "/" + WAHLEN_ZIP));
      zos.write(writeWahlen(map));
      zos.closeEntry();

      String wahlId = createWahlId(context);
      LOG.info("WahlId: '" + wahlId + "'");

      zos.putNextEntry(new ZipEntry(WAHL_DIR + "/" + CONFIG_WAHL_BAT));
      zos.write(createConfigWahlBat(wahlId));
      zos.closeEntry();

      zos.putNextEntry(new ZipEntry(WAHL_DIR + "/" + CONFIG_WAHL_SH));
      zos.write(createConfigWahlSh(wahlId));
      zos.closeEntry();

      try (ZipInputStream templateStream = createTemplateStream(context)) {
        if (templateStream != null) {
          ZipEntry entry;
          while ((entry = templateStream.getNextEntry()) != null) {
            zos.putNextEntry(entry);
            IOUtils.copy(templateStream, zos, COPY_BUFFER);
            zos.closeEntry();
          }
        }
      }

      zos.finish();
    } catch (IOException e) {
      throw new RuntimeException(e.getMessage(), e);
    }
  }

  @Override
  protected FileType getFileType() {
    return FileType.ZIP;
  }

  @Override
  public int getPriority() {
    return LOWER_PRIORITY;
  }
}
