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

import static org.apache.commons.lang3.StringUtils.isBlank;

import java.io.InputStream;
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.gebietsbaum.boundary.GebietsartTemplate;
import de.ivu.elect.business.gebietsbaum.boundary.WahldurchfuehrungsgebietFactory;
import de.ivu.elect.business.gebietsbaum.entity.AnzahlWahlberechtigteImportContext;
import de.ivu.elect.business.gebietsbaum.entity.AnzahlWahlberechtigteImportObjekt;
import de.ivu.elect.business.gebietsbaum.entity.Gebietsart;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.exchange.CsvImportMapper;
import de.ivu.elect.exchange.csv.CsvMarshaller;
import de.ivu.elect.jee.exchange.Violations;

public abstract class AbstractAnzahlWahlberechtigteCsvImportMapper
    implements
      AnzahlWahlberechtigteImportMapper,
      CsvImportMapper<AnzahlWahlberechtigteImportObjekt, AnzahlWahlberechtigteImportContext> {

  public static final String FILE_FORMAT_NAME = "file.format.gebietsbaum.was.anzahl.wahlberechtigte";

  @Inject
  private transient CsvMarshaller csvMarshaller;

  @Inject
  private transient WahldurchfuehrungsgebietFactory wahldurchfuehrungsgebietFactory;

  public AbstractAnzahlWahlberechtigteCsvImportMapper() {
    super();
  }

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

  @Override
  public List<String> getCsvColumnHeaders(AnzahlWahlberechtigteImportContext context) {
    return csvMarshaller.extractHeader(CsvWahlberechtigte.class);
  }

  @Override
  public AnzahlWahlberechtigteImportObjekt deserialize(InputStream is, AnzahlWahlberechtigteImportContext context, FileKonfiguration fileKonfiguration) throws MappingException {
    List<CsvWahlberechtigte> dtos = deserialize(is, fileKonfiguration);

    List<Wahldurchfuehrungsgebiet> gebiete = new ArrayList<>(dtos.size());

    Gebietsart gebietsart = new Gebietsart();
    gebietsart.setName(getGebietsartMitWahlberechtigten().getGebietsartName());

    for (CsvWahlberechtigte dto : dtos) {
      Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet = createWahldurchfuehrungsgebiet();
      wahldurchfuehrungsgebiet.setNummer(extractGebietsnummer(dto.getGebietsnummer()));
      wahldurchfuehrungsgebiet.setGebietsart(gebietsart);

      wahldurchfuehrungsgebiet.setAnzahlWahlberechtigteOhneWahlschein(parseLong(dto.getAnzahlWahlberechtigteOhneWahlschein()));
      wahldurchfuehrungsgebiet.setAnzahlWahlberechtigteMitWahlschein(parseLong(dto.getAnzahlWahlberechtigteMitWahlschein()));
      wahldurchfuehrungsgebiet.setAnzahlWahlberechtigteNichtImWaehlerverzeichnis(parseLong(dto.getAnzahlWahlberechtigteNichtImWaehlerverzeichnis()));

      gebiete.add(wahldurchfuehrungsgebiet);
    }

    return new AnzahlWahlberechtigteImportObjekt(gebiete);
  }

  protected List<CsvWahlberechtigte> deserialize(InputStream is, FileKonfiguration fileKonfiguration) {
    return csvMarshaller.deserialize(CsvWahlberechtigte.class, is, fileKonfiguration);
  }

  protected abstract String extractGebietsnummer(String gebietsnummer);

  protected abstract GebietsartTemplate getGebietsartMitWahlberechtigten();

  @Override
  public Violations validateInputFormat(InputStream is, AnzahlWahlberechtigteImportContext context, FileKonfiguration fileKonfiguration) {
    return new Violations();
  }

  protected Wahldurchfuehrungsgebiet createWahldurchfuehrungsgebiet() {
    return wahldurchfuehrungsgebietFactory.create();
  }

  private Long parseLong(String string) {
    if (isBlank(string)) {
      return 0L;
    }

    return Long.valueOf(string);
  }
}
