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

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

import javax.inject.Inject;

import de.ivu.elect.business.exchange.control.FileKonfiguration;
import de.ivu.elect.business.exchange.control.MappingException;
import de.ivu.elect.business.gebietsbaum.control.Gebietsbaum;
import de.ivu.elect.business.gebietsbaum.control.GebietsbaumExchangeContext;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.exchange.CsvImportMapper;
import de.ivu.elect.exchange.csv.CsvMarshaller;
import de.ivu.elect.jee.exchange.Violations;

public abstract class AbstractGebietAktualisierenCsvImportMapper<DTO> extends AbstractGebietsbaumImportMapper implements CsvImportMapper<Gebietsbaum, GebietsbaumExchangeContext> {

  @Inject
  private transient CsvMarshaller csvMarshaller;

  public AbstractGebietAktualisierenCsvImportMapper() {
    super();
  }

  @Override
  protected boolean isAcceptContextWurzelgebietNichtVorhanden(GebietsbaumExchangeContext context) {
    return false;
  }

  protected abstract Class<DTO> getDtoClass();

  @Override
  public List<String> getCsvColumnHeaders(GebietsbaumExchangeContext context) {
    return csvMarshaller.extractHeader(getDtoClass());
  }

  @Override
  public Violations validateInputFormat(InputStream is, GebietsbaumExchangeContext context, FileKonfiguration fileKonfiguration) {
    return validateDTOs(deserialize(is, fileKonfiguration), context);
  }

  protected Violations validateDTOs(List<DTO> dtos, GebietsbaumExchangeContext context) {
    return new Violations();
  }

  @Override
  public Gebietsbaum deserialize(InputStream is, GebietsbaumExchangeContext context, FileKonfiguration fileKonfiguration) throws MappingException {
    if (!getGebietImportAktualisierenArt().equals(context.getGebietImportAktualisierenArt())) {
      throw new IllegalStateException(context.getGebietImportAktualisierenArt() + " ist nicht erlaubt!");
    }

    return mapExternToIntern(deserialize(is, fileKonfiguration));
  }

  private List<DTO> deserialize(InputStream is, FileKonfiguration fileKonfiguration) {
    return csvMarshaller.deserialize(getDtoClass(), is, fileKonfiguration);
  }

  private Gebietsbaum mapExternToIntern(List<DTO> dtos) {
    List<Gebiet> gebiete = new ArrayList<>();

    for (DTO dto : dtos) {
      gebiete.add(mapDtoToGebiet(dto));
    }

    return new Gebietsbaum(wahlFactory.create(), gebiete);
  }

  protected abstract Gebiet mapDtoToGebiet(DTO dto);
}
