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

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

import javax.inject.Inject;

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.statistik.boundary.StatistikKennzeichenDAO;
import de.ivu.elect.business.statistik.control.StatistikLaufExportContext;
import de.ivu.elect.business.statistik.entity.StatistikKennzeichen;
import de.ivu.elect.business.statistik.entity.StatistikLauf;
import de.ivu.elect.exchange.csv.CsvMarshaller;
import de.ivu.elect.exchange.statistik.StatistikLaufExportMapper;

public class StatistikLaufCsvExportMapper implements StatistikLaufExportMapper {

  public static final String FILE_FORMAT_NAME = "file.format.statistik.lauf.export.default";

  @Inject
  private transient CsvMarshaller csvMarshaller;

  @Inject
  private transient StatistikKennzeichenDAO statistikKennzeichenDAO;

  public StatistikLaufCsvExportMapper() {
    super();
  }

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

  @Override
  public boolean isAcceptContext(StatistikLaufExportContext statistikLaufExportContext) {
    return statistikLaufExportContext.getWahltermin() != null;
  }

  @Override
  public void serialize(List<StatistikLauf> statistikLaeufe, OutputStream os, StatistikLaufExportContext statistikLaufExportContext, FileKonfiguration fileKonfiguration) throws MappingException {
    for (int i = 0; i < statistikLaeufe.size(); i++) {
      StatistikLauf statistikLauf = statistikLaeufe.get(i);
      boolean isLastElement = i + 1 == statistikLaeufe.size();

      StatistikLauf_LaufMitKennzeichenCsvDTO laufMitKennzeichenCsvDTO = createStatistikLaufMitStatistikKennzeichenCsvDTO(statistikLauf, statistikLaufExportContext, isLastElement);

      serialize(os, fileKonfiguration, laufMitKennzeichenCsvDTO);
    }
  }

  private void serialize(OutputStream os, FileKonfiguration fileKonfiguration, StatistikLauf_LaufMitKennzeichenCsvDTO laufMitKennzeichenCsvDTO) {
    serialize(os, fileKonfiguration, laufMitKennzeichenCsvDTO.isLastDTO() && !laufMitKennzeichenCsvDTO.hasStatistikKennzeichenDTOs(), laufMitKennzeichenCsvDTO.getStatistikLauf_laufCsvDTOs());
    serialize(os, fileKonfiguration, laufMitKennzeichenCsvDTO.isLastDTO(), laufMitKennzeichenCsvDTO.getStatistikLauf_kennzeichenCsvDTOs());
  }

  protected void serialize(OutputStream os, FileKonfiguration fileKonfiguration, boolean closeOutputStream, List<StatistikLaufCsvDTO> dtos) {
    if (!dtos.isEmpty()) {
      csvMarshaller.serialize((Class<StatistikLaufCsvDTO>) dtos.get(0).getClass(), dtos, os, fileKonfiguration, closeOutputStream);
    }
  }

  private StatistikLauf_LaufMitKennzeichenCsvDTO createStatistikLaufMitStatistikKennzeichenCsvDTO(StatistikLauf statistikLauf, StatistikLaufExportContext statistikLaufExportContext,
      boolean isLastElement) {
    StatistikLauf_LaufMitKennzeichenCsvDTO laufMitKennzeichenDTO = new StatistikLauf_LaufMitKennzeichenCsvDTO();

    laufMitKennzeichenDTO.setStatistikLauf_laufCsvDTOs(createLaufCsvDTO(statistikLauf, statistikLaufExportContext));
    laufMitKennzeichenDTO.setStatistikLauf_kennzeichenCsvDTOs(createKennzeichenCsvDTOs(statistikLauf, statistikLaufExportContext));

    laufMitKennzeichenDTO.setLastDTO(isLastElement);

    return laufMitKennzeichenDTO;
  }

  private List<StatistikLaufCsvDTO> createLaufCsvDTO(StatistikLauf statistikLauf, StatistikLaufExportContext statistikLaufExportContext) {
    List<StatistikLaufCsvDTO> result = new ArrayList<>();

    StatistikLauf_LaufCsvDTO laufCsvDTO = new StatistikLauf_LaufCsvDTO();

    if (statistikLauf.getWahl() != null) {
      laufCsvDTO.setWahlartName(statistikLauf.getWahl().getWahlart().getName());
    }

    laufCsvDTO.setAusloeser(statistikLauf.getAusloeser());
    laufCsvDTO.setStatus(statistikLauf.getStatus().name());
    laufCsvDTO.setBeschreibung(statistikLauf.getBeschreibung());
    laufCsvDTO.setZeitpunktDesLaufs(statistikLauf.getZeitpunktDesLaufs());
    laufCsvDTO.setStartDesLaufs(statistikLauf.getStartDesLaufs());
    laufCsvDTO.setEndeDesLaufs(statistikLauf.getEndeDesLaufs());

    result.add(laufCsvDTO);

    return result;
  }

  private List<StatistikLaufCsvDTO> createKennzeichenCsvDTOs(StatistikLauf statistikLauf, StatistikLaufExportContext statistikLaufExportContext) {
    List<StatistikLaufCsvDTO> result = new ArrayList<>();

    List<StatistikKennzeichen> alleStatistikKennzeichenEinesLaufs = statistikKennzeichenDAO.findByLauf(statistikLauf);

    for (StatistikKennzeichen statistikKennzeichen : alleStatistikKennzeichenEinesLaufs) {
      StatistikLauf_KennzeichenCsvDTO kennzeichenCsvDTO = new StatistikLauf_KennzeichenCsvDTO();

      if (statistikKennzeichen.getGebiet() != null) {
        kennzeichenCsvDTO.setGebietsartName(statistikKennzeichen.getGebiet().getGebietsart().getName());
        kennzeichenCsvDTO.setGebietsNummer(statistikKennzeichen.getGebiet().getNummer());
      }

      if (statistikKennzeichen.getWahl() != null) {
        kennzeichenCsvDTO.setWahlartName(statistikKennzeichen.getWahl().getWahlart().getName());
      }

      kennzeichenCsvDTO.setKennzeichen(statistikKennzeichen.getKennzeichen().name());
      kennzeichenCsvDTO.setQualifier(statistikKennzeichen.getQualifier());
      kennzeichenCsvDTO.setWert(statistikKennzeichen.getWert());

      result.add(kennzeichenCsvDTO);
    }

    return result;
  }

}
