
package de.ivu.elect.was.exchange.stimmeingabe;

import java.io.OutputStream;
import java.util.List;

import javax.inject.Inject;
import javax.xml.bind.JAXBException;

import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.exchange.control.FileKonfiguration;
import de.ivu.elect.business.exchange.control.MappingException;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeExportContext;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingang;
import de.ivu.elect.interfaces.was.stimmeingabe.ErfassteStimmen;
import de.ivu.elect.jee.exchange.XmlMarshaller;

public abstract class AbstractWasStimmeingabeXMLExportMapper extends AbstractWasEingabeXMLExportMapper implements StimmeingabeExportMapper {

  public static final String FORMAT_NAME = "file.format.stimmeingaben";

  @Inject
  protected transient XmlMarshaller<ErfassteStimmen> xmlMarshaller;

  public AbstractWasStimmeingabeXMLExportMapper() {
    super();
  }

  @Override
  public void serialize(List<Ergebniseingang> ergebniseingaenge, OutputStream os, StimmeingabeExportContext stimmeingabeExportContext, FileKonfiguration fileKonfiguration) throws MappingException {
    serialize(mappe(ergebniseingaenge), os, stimmeingabeExportContext, fileKonfiguration);
  }

  public void serialize(ErfassteStimmen erfassteStimmen, OutputStream os, StimmeingabeExportContext stimmeingabeExportContext,
                        FileKonfiguration fileKonfiguration) throws MappingException {
    try {
      xmlMarshaller.serialize(erfassteStimmen, os);
    } catch (JAXBException e) {
      throw new MappingException(e.getMessage(), e);
    }
  }

  public ErfassteStimmen mappe(List<Ergebniseingang> ergebniseingaenge) {
    ErfassteStimmen erfassteStimmen = new ErfassteStimmen();

    if (ergebniseingaenge.isEmpty()) {
      return erfassteStimmen;
    }

    mappeWahl(erfassteStimmen, ergebniseingaenge.get(0));

    WasStimmeingabeXMLExportMapperMaps maps = new WasStimmeingabeXMLExportMapperMaps(wahlInternExternMapperUtil);

    for (Ergebniseingang ergebniseingang : ergebniseingaenge) {
      if (isGeloeschterEingang(ergebniseingang)) {
        erfassteStimmen.getGeloeschterErgebniseingaenge().add(mappeGeloescht(ergebniseingang, maps));
      } else {
        erfassteStimmen.getErgebniseingaenge().add(mappe(ergebniseingang, maps));
      }
    }

    return erfassteStimmen;
  }

  public static boolean isGeloeschterEingang(Ergebniseingang ergebniseingang) {
    return ergebniseingang.getStimmeingaben().isEmpty();
  }

  @Override
  public boolean isAcceptContext(StimmeingabeExportContext context) {
    return context.getWahldurchfuehrung() != null;
  }

  @Override
  public FileFormat getFileFormat() {
    return new FileFormat(FORMAT_NAME, getFileType());
  }

  protected abstract FileType getFileType();
}
