
package de.ivu.elect.core.exchange.ergebnis;

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.ergebnis.boundary.SitzeFactory;
import de.ivu.elect.business.ergebnis.control.SitzeImportContext;
import de.ivu.elect.business.ergebnis.entity.Sitze;
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.GebietFactory;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.Gebietsart;
import de.ivu.elect.business.gruppe.boundary.PolitischeGruppeFactory;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.exchange.CsvImportMapper;
import de.ivu.elect.exchange.csv.CsvMarshaller;
import de.ivu.elect.jee.exchange.Violations;

public class DefaultSitzeCsvImportMapper implements SitzeImportMapper, CsvImportMapper<List<Sitze>, SitzeImportContext> {

  public static final String FILE_FORMAT_NAME = "file.format.sitze.default";
  public static final FileFormat FILE_FORMAT = new FileFormat(FILE_FORMAT_NAME, FileType.CSV);

  @Inject
  private transient CsvMarshaller csvMarshaller;

  @Inject
  private transient SitzeFactory sitzeFactory;

  @Inject
  private transient GebietFactory gebietFactory;

  @Inject
  private transient PolitischeGruppeFactory politischeGruppeFactory;

  public DefaultSitzeCsvImportMapper() {
    super();
  }

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

  @Override
  public List<Sitze> deserialize(InputStream is, SitzeImportContext sitzeImportContext, FileKonfiguration fileKonfiguration) throws MappingException {
    return mappeDtoToEntity(deserialize(is, fileKonfiguration));
  }

  private List<Sitze> mappeDtoToEntity(List<SitzeCsvDTO> dtos) {
    ArrayList<Sitze> result = new ArrayList<>();

    for (SitzeCsvDTO dto : dtos) {
      Sitze sitze = sitzeFactory.create();
      sitze.setAnzahl(dto.getAnzahlSitze());
      sitze.setAnzahlAnspruch(dto.getAnzahlAnspruch() != null ? dto.getAnzahlAnspruch() : dto.getAnzahlSitze());

      Gebiet gebiet = gebietFactory.create();
      sitze.setGebiet(gebiet);
      Gebietsart gebietsart = new Gebietsart();
      gebietsart.setName(dto.getGebietsartName());
      gebiet.setGebietsart(gebietsart);
      gebiet.setNummer(dto.getGebietNummer());

      PolitischeGruppe politischeGruppe = politischeGruppeFactory.create();
      politischeGruppe.setSchluessel(dto.getGruppeSchluessel());
      sitze.setGruppe(politischeGruppe);

      result.add(sitze);
    }

    return result;
  }

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

  @Override
  public Violations validateInputFormat(InputStream is, SitzeImportContext sitzeImportContext, FileKonfiguration fileKonfiguration) {
    Violations violations = new Violations();
    List<SitzeCsvDTO> dtos = deserialize(is, fileKonfiguration);

    // TODO ELECT-4511: Was ist hier zu prüfen?

    return violations;
  }

  @Override
  public FileFormat getFileFormat() {
    return FILE_FORMAT;
  }

  @Override
  public boolean isAcceptContext(SitzeImportContext sitzeImportContext) {
    return true; // TODO ELECT-4511: Was ist hier zu prüfen? Ist SitzeImportContext  die richtige Klasse?
  }
}
