
package de.ivu.elect.exchange.staat;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

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.exchange.control.NoContext;
import de.ivu.elect.business.staat.boundary.StaatFactory;
import de.ivu.elect.business.staat.entity.Staat;
import de.ivu.elect.exchange.CsvImportMapper;
import de.ivu.elect.exchange.csv.CsvMarshaller;
import de.ivu.elect.jee.exchange.Violations;

public class DefaultStaatCsvMapper implements StaatMapper, CsvImportMapper<List<Staat>, NoContext> {

  public static final String FORMAT_NAME = "file.format.staat.export.default";

  @Inject
  private transient CsvMarshaller csvMarshaller;

  @Inject
  private transient StaatFactory staatFactory;

  public DefaultStaatCsvMapper() {
    super();
  }

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

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

  @Override
  public void serialize(List<Staat> staaten, OutputStream outputStream, NoContext noContext, FileKonfiguration fileKonfiguration) throws MappingException {
    csvMarshaller.serialize(DefaultStaatCsvDTO.class, staaten.stream().map(staatToDto()).collect(Collectors.toList()), outputStream, fileKonfiguration);
  }

  private Function<Staat, DefaultStaatCsvDTO> staatToDto() {
    return staat -> {
      DefaultStaatCsvDTO dto = new DefaultStaatCsvDTO();
      dto.setCodeStaat(staat.getCustomCodeStaat());
      dto.setCodeStaatsangehoerigkeit(staat.getCustomCodeStaatsangehoerigkeit());
      dto.setNameStaat(staat.getNameStaat());
      dto.setNameStaatsangehoerigkeit(staat.getNameStaatsangehoerigkeit());
      dto.setEuStaat(staat.getEuStaat());
      dto.setIso3166Alpha2(staat.getIso3166Alpha2());
      dto.setIso3166Numerisch(staat.getIso3166Numerisch());

      return dto;
    };
  }

  @Override
  public List<Staat> deserialize(InputStream inputStream, NoContext noContext, FileKonfiguration fileKonfiguration) throws MappingException {
    return csvMarshaller.deserialize(DefaultStaatCsvDTO.class, inputStream, fileKonfiguration).stream().map(dtoToStaat()).collect(Collectors.toList());
  }

  private Function<DefaultStaatCsvDTO, Staat> dtoToStaat() {
    return dto -> {
      Staat staat = staatFactory.create();
      staat.setCustomCodeStaat(dto.getCodeStaat());
      staat.setCustomCodeStaatsangehoerigkeit(dto.getCodeStaatsangehoerigkeit());
      staat.setNameStaat(dto.getNameStaat());
      staat.setNameStaatsangehoerigkeit(dto.getNameStaatsangehoerigkeit());
      staat.setEuStaat(dto.getEuStaat());
      staat.setIso3166Alpha2(dto.getIso3166Alpha2());
      staat.setIso3166Numerisch(dto.getIso3166Numerisch());

      return staat;
    };
  }

  @Override
  public boolean isAcceptContext(NoContext noContext) {
    return true;
  }

  @Override
  public Violations validateInputFormat(InputStream inputStream, NoContext noContext, FileKonfiguration fileKonfiguration) {
    return new Violations();
  }
}
