
package de.ivu.elect.exchange.entschaedigung.csv;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.inject.Inject;

import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.entschaedigung.control.AuszahlungExportContext;
import de.ivu.elect.business.entschaedigung.control.AuszahlungExportObject;
import de.ivu.elect.business.entschaedigung.entity.Auszahlung;
import de.ivu.elect.business.entschaedigung.entity.AuszahlungCalculated;
import de.ivu.elect.business.entschaedigung.entity.Entschaedigung;
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.person.entity.Personendaten;
import de.ivu.elect.exchange.csv.CsvDescriptor;
import de.ivu.elect.exchange.csv.CsvMarshaller;
import de.ivu.elect.exchange.entschaedigung.AuszahlungExportMapper;

public abstract class AbstractDefaultAuszahlungEntschaedigungPerPersonendatenCsvExportMapper implements AuszahlungExportMapper {

  @Inject
  private transient CsvMarshaller csvMarshaller;

  protected AbstractDefaultAuszahlungEntschaedigungPerPersonendatenCsvExportMapper() {
    super();
  }

  @Override
  public boolean isAcceptContext(AuszahlungExportContext context) {
    return true; // NOTE, dass KEINE Auszahlung tatsächlich OK ist, da diese auf dem Export-View auswählbar ist, cf. AuszahlungExportView#AuszahlungProperty!
  }

  @Override
  public FileFormat getFileFormat() {
    return new FileFormat(getFileFormatName(), FileType.CSV);
  }

  protected abstract String getFileFormatName();

  @Override
  public void serialize(AuszahlungExportObject exportObject, OutputStream os, AuszahlungExportContext context, FileKonfiguration fileKonfiguration) throws MappingException {
    CsvDescriptor csvDescriptor = CsvDescriptor.forFileKonfiguration(fileKonfiguration);
    csvDescriptor.setWithHeader(true);

    csvMarshaller.serialize(DefaultAuszahlungEntschaedigungPerPersonendatenCsvExportDTO.class, createDtos(context, exportObject.getAuszahlungCalculated()), os, csvDescriptor);
  }

  protected List<DefaultAuszahlungEntschaedigungPerPersonendatenCsvExportDTO> createDtos(AuszahlungExportContext context, AuszahlungCalculated auszahlungCalculated) {
    List<DefaultAuszahlungEntschaedigungPerPersonendatenCsvExportDTO> result = new ArrayList<>();

    Auszahlung auszahlung = auszahlungCalculated.getAuszahlung();

    for (Entry<Personendaten, List<Entschaedigung>> entschaedigungPerPersonendaten : collectEntschaedigungenPerPersonendaten(auszahlungCalculated).entrySet()) {
      Personendaten personendaten = entschaedigungPerPersonendaten.getKey();

      for (Entschaedigung entschaedigung : entschaedigungPerPersonendaten.getValue()) {
        result.add(new DefaultAuszahlungEntschaedigungPerPersonendatenCsvExportDTO(auszahlung, personendaten, entschaedigung, context.getLocale()));
      }
    }

    return result;
  }

  protected abstract Map<Personendaten, List<Entschaedigung>> collectEntschaedigungenPerPersonendaten(AuszahlungCalculated auszahlungCalculated);
}
