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

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.benutzerverwaltung.entity.BenutzerEinsatzort;
import de.ivu.elect.business.benutzerverwaltung.entity.BenutzerEinsatzortExchangeContext;
import de.ivu.elect.business.benutzerverwaltung.entity.Rolle;
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.exchange.CsvImportMapper;
import de.ivu.elect.exchange.benutzer.BenutzerEinsatzortMapper;
import de.ivu.elect.exchange.benutzer.DefaultRolle;
import de.ivu.elect.exchange.csv.CsvMarshaller;
import de.ivu.elect.jee.exchange.Violations;

import static de.ivu.elect.exchange.benutzer.AbstractDefaultBenutzerMapper.convertToDefaultRollen;

public class DefaultCsvBenutzerEinsatzortMapper implements CsvImportMapper<List<BenutzerEinsatzort>, BenutzerEinsatzortExchangeContext>, BenutzerEinsatzortMapper {

  public static final String FILE_FORMAT_NAME = "file.format.benutzer.einsatzort.default";

  @Inject
  private transient CsvMarshaller csvMarshaller;

  public DefaultCsvBenutzerEinsatzortMapper() {
    super();
  }

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

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

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

  @Override
  public void serialize(List<BenutzerEinsatzort> object, OutputStream os, BenutzerEinsatzortExchangeContext noContext, FileKonfiguration fileKonfiguration) throws MappingException {
    csvMarshaller.serialize(DefaultCsvBenutzerEinsatzort.class, mappeBenutzerEinsatzortInternToExtern(object), os, fileKonfiguration);
  }

  protected List<DefaultCsvBenutzerEinsatzort> mappeBenutzerEinsatzortInternToExtern(List<BenutzerEinsatzort> benutzerEinsatzorts) {
    List<DefaultCsvBenutzerEinsatzort> mappedBenutzerEinsatzorte = new ArrayList<>(benutzerEinsatzorts.size());
    for (BenutzerEinsatzort benutzerEinsatzort : benutzerEinsatzorts) {
      mappedBenutzerEinsatzorte.add(mappeBenutzerEinsatzort(benutzerEinsatzort));
    }
    return mappedBenutzerEinsatzorte;
  }

  protected DefaultCsvBenutzerEinsatzort mappeBenutzerEinsatzort(de.ivu.elect.business.benutzerverwaltung.entity.BenutzerEinsatzort from) {
    DefaultCsvBenutzerEinsatzort to = new DefaultCsvBenutzerEinsatzort();
    to.setName(from.getName());
    to.setBemerkung(from.getBemerkung());
    to.setBesonderheit(from.getBesonderheit());
    to.setClientIpMuster(from.getClientIpMuster());
    to.setRollen(convertToDefaultRollen(from.getRolles()));
    return to;
  }

  @Override
  public List<BenutzerEinsatzort> deserialize(InputStream is, BenutzerEinsatzortExchangeContext noContext, FileKonfiguration fileKonfiguration) throws MappingException {
    return mappeBenutzerEinsatzorteExternToIntern(csvMarshaller.deserialize(DefaultCsvBenutzerEinsatzort.class, is, fileKonfiguration));
  }

  protected List<BenutzerEinsatzort> mappeBenutzerEinsatzorteExternToIntern(List<DefaultCsvBenutzerEinsatzort> benutzerEinsatzorteListe) {
    List<BenutzerEinsatzort> mappedBenutzerEinsatzorte = new ArrayList<>(benutzerEinsatzorteListe.size());
    for (DefaultCsvBenutzerEinsatzort benutzerEinsatzort : benutzerEinsatzorteListe) {
      mappedBenutzerEinsatzorte.add(mappeBenutzerEinsatzort(benutzerEinsatzort));
    }
    return mappedBenutzerEinsatzorte;
  }

  protected BenutzerEinsatzort mappeBenutzerEinsatzort(DefaultCsvBenutzerEinsatzort from) {
    BenutzerEinsatzort to = new BenutzerEinsatzort();
    to.setName(from.getName());
    to.setBesonderheit(from.getBesonderheit());
    to.setBemerkung(from.getBemerkung());
    to.setClientIpMuster(from.getClientIpMuster());
    setRollen(from, to);
    return to;
  }

  private void setRollen(DefaultCsvBenutzerEinsatzort from, BenutzerEinsatzort to) {
    if (from.getRollen() != null) {
      for (DefaultRolle rolle : from.getRollen()) {
        Rolle deserialiserteRolle = new Rolle();
        deserialiserteRolle.setName(rolle.getName());
        to.addRolle(deserialiserteRolle);
      }
    }
  }

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