
package de.ivu.elect.exchange.person;

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

import javax.inject.Inject;

import de.ivu.elect.business.datei.entity.CsvAnfuehrungszeichen;
import de.ivu.elect.business.datei.entity.CsvMaskierungszeichen;
import de.ivu.elect.business.datei.entity.CsvTrennzeichen;
import de.ivu.elect.business.datei.entity.CsvZeichensatz;
import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.exchange.control.CsvFileKonfiguration;
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.person.boundary.DefaultBerufeExportMapper;
import de.ivu.elect.business.person.entity.Beruf;
import de.ivu.elect.exchange.CsvImportMapper;
import de.ivu.elect.exchange.csv.CsvMarshaller;
import de.ivu.elect.jee.exchange.Violations;

public class DefaultBerufCsvMapper implements BerufMapper, CsvImportMapper<List<Beruf>, NoContext>, DefaultBerufeExportMapper {

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

  @Inject
  private transient CsvMarshaller csvMarshaller;

  public DefaultBerufCsvMapper() {
    super();
  }

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

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

  @Override
  public void serialize(List<Beruf> object, OutputStream os, NoContext noContext, FileKonfiguration fileKonfiguration) throws MappingException {
    csvMarshaller.serialize(DefaultBerufCsvDTO.class, mappeEntityToDto(object), os, fileKonfiguration);
  }

  @Override
  public void serialize(List<Beruf> berufe, OutputStream os) {
    try {
      serialize(berufe, os, NoContext.NO_CONTEXT, new CsvFileKonfiguration() {
        @Override
        public FileFormat getFileFormat() {
          return DefaultBerufCsvMapper.this.getFileFormat();
        }

        @Override
        public CsvZeichensatz getZeichensatz() {
          return CsvZeichensatz.UTF_8;
        }

        @Override
        public Boolean isWithHeader() {
          return Boolean.TRUE;
        }

        @Override
        public Long getAnzahlKopfzeilen() {
          return 1L;
        }

        @Override
        public CsvTrennzeichen getTrennzeichen() {
          return CsvTrennzeichen.SEMIKOLON;
        }

        @Override
        public Boolean isNutzeTrennzeichenNachLetztemFeld() {
          return Boolean.FALSE;
        }

        @Override
        public CsvAnfuehrungszeichen getAnfuehrungszeichen() {
          return CsvAnfuehrungszeichen.DOPPELT;
        }

        @Override
        public CsvMaskierungszeichen getMaskierungszeichen() {
          return CsvMaskierungszeichen.getDefault();
        }
      });
    } catch (MappingException e) {
      throw new RuntimeException(e);
    }

  }




  private List<DefaultBerufCsvDTO> mappeEntityToDto(List<Beruf> object) {
    List<DefaultBerufCsvDTO> result = new ArrayList<>();
    for (Beruf beruf : object) {
      DefaultBerufCsvDTO dto = new DefaultBerufCsvDTO();
      dto.setCode(beruf.getCode());
      dto.setHerkunft(beruf.getHerkunft());
      dto.setName(beruf.getName());
      dto.setGeschlecht(beruf.getGeschlecht());

      result.add(dto);
    }

    return result;
  }

  @Override
  public List<Beruf> deserialize(InputStream is, NoContext noContext, FileKonfiguration fileKonfiguration) throws MappingException {
    return mappeDtoToEntity(csvMarshaller.deserialize(DefaultBerufCsvDTO.class, is, fileKonfiguration));
  }

  private List<Beruf> mappeDtoToEntity(List<DefaultBerufCsvDTO> deserialize) {
    List<Beruf> result = new ArrayList<>();

    for (DefaultBerufCsvDTO dto : deserialize) {
      Beruf beruf = new Beruf();
      beruf.setCode(dto.getCode());
      beruf.setHerkunft(dto.getHerkunft());
      beruf.setName(dto.getName());
      if (dto.getGeschlecht()!=null) {
        beruf.setGeschlecht(dto.getGeschlecht());
      }

      result.add(beruf);
    }

    return result;
  }

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

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

}
