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

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

import javax.inject.Inject;
import javax.xml.bind.JAXBException;

import de.ivu.elect.business.benutzerverwaltung.control.BenutzerExchangeContext;
import de.ivu.elect.business.benutzerverwaltung.entity.Benutzer;
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.konfiguration.entity.KonfigurationLoader;
import de.ivu.elect.business.konfiguration.entity.MandantKonfigurationWerte;
import de.ivu.elect.business.security.entity.TwoFactorAuthenticationStatus;
import de.ivu.elect.exchange.benutzer.AbstractDefaultBenutzerMapper;
import de.ivu.elect.jee.exchange.Violations;
import de.ivu.elect.jee.exchange.XmlMarshaller;

public class Xml2FABenutzerMapper extends AbstractDefaultBenutzerMapper<Xml2FABenutzer> {

  public static final String FILE_FORMAT_NAME = "file.format.benutzer.2fa";

  @Inject
  protected transient XmlMarshaller<Xml2FABenutzerListe> xmlMarshaller;

  @Inject
  private transient KonfigurationLoader konfigurationLoader;

  @Override
  protected Xml2FABenutzer createBenutzer() {
    return new Xml2FABenutzer();
  }

  protected Xml2FABenutzerListe mappeBenutzerInternToExtern(List<Benutzer> benutzerListe) {
    Xml2FABenutzerListe result = new Xml2FABenutzerListe();
    for (Benutzer benutzer : benutzerListe) {
      result.getBenutzer().add(mappeBenutzer(benutzer));
    }

    return result;
  }

  protected List<Benutzer> mappeBenutzerExternToIntern(Xml2FABenutzerListe benutzerListe) {
    List<Benutzer> result = new ArrayList<>(benutzerListe.getBenutzer().size());
    for (Xml2FABenutzer benutzer : benutzerListe.getBenutzer()) {
      result.add(mappeBenutzer(benutzer));
    }

    return result;
  }

  @Override
  protected Xml2FABenutzer mappeBenutzer(Benutzer from) {
    Xml2FABenutzer xml2FABenutzer = super.mappeBenutzer(from);
    xml2FABenutzer.setHotpSecret(from.getHotpSecret());
    xml2FABenutzer.setTanListe(from.getTanliste());
    return xml2FABenutzer;
  }

  @Override
  protected Benutzer mappeBenutzer(Xml2FABenutzer from) {
    Benutzer benutzer = super.mappeBenutzer(from);
    benutzer.setHotpSecret(from.getHotpSecret());
    benutzer.setTanliste(from.getTanListe());
    return benutzer;
  }

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

  @Override
  public void serialize(List<Benutzer> object, OutputStream os, BenutzerExchangeContext context, FileKonfiguration fileKonfiguration)
      throws MappingException {
    try {
      xmlMarshaller.serialize(mappeBenutzerInternToExtern(object), os);
    } catch (JAXBException e) {
      throw new MappingException(e.getMessage(), e);
    }
  }

  @Override
  public List<Benutzer> deserialize(InputStream is, BenutzerExchangeContext context, FileKonfiguration fileKonfiguration)
      throws MappingException {
    try {
      return mappeBenutzerExternToIntern(xmlMarshaller.deserialize(Xml2FABenutzerListe.class, is));
    } catch (JAXBException e) {
      throw new MappingException(e.getMessage(), e);
    }
  }

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

  @Override
  public boolean isAcceptContext(BenutzerExchangeContext context) {
    if (context.getMandant()==null){
      return false;
    }
    TwoFactorAuthenticationStatus twoFactorAuthenticationStatus = konfigurationLoader.resolveEnumValue(context.getMandant(), MandantKonfigurationWerte.TWO_FACTOR_AUTHENTICATION_STATUS, TwoFactorAuthenticationStatus.class);
    return twoFactorAuthenticationStatus != null && twoFactorAuthenticationStatus.isAktiv();
  }
}
