
package de.ivu.elect.dokumente.ergebnis;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;

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

import javax.inject.Inject;

import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.dokumente.boundary.DokumentVorlageDAO;
import de.ivu.elect.business.ergebnis.boundary.GesamtErgebnisDokumentContext;
import de.ivu.elect.business.ergebnis.control.ErgebnisExchangeContext;
import de.ivu.elect.business.ergebnis.control.NlWasErgebnisArtefaktNachGebietErgebniseingabestatusExportContext;
import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.exchange.control.FileKonfiguration;
import de.ivu.elect.business.wahl.control.AbstractNlExportArtefaktNachSystemExportstatusExportContext;
import de.ivu.elect.business.wahl.control.NlExportArtefaktNachSystemExportstatusExportObject;
import de.ivu.elect.dokumente.wahl.NlExportArtefaktNachSystemExportstatussDocumentExportMapper;
import de.ivu.elect.was.exchange.wahl.AbstractNlWasExportArtefaktNachGebietErgebniseingabestatusExportMapper;

// Cf. AbstractNlWusWahlvorschlagdokumentNachNlWahlPhaseDocumentExportMapper!
public abstract class AbstractNlWasGesamtErgebnisDokumentNachGebietErgebniseingabestatusDocumentExportMapper extends AbstractNlWasExportArtefaktNachGebietErgebniseingabestatusExportMapper {

  @Inject
  private transient DokumentVorlageDAO dokumentVorlageDAO;

  @Inject
  private transient NlWasErgebnisdokumentNachGebietErgebniseingabestatusByGesamtErgebnisDokumentGeneratorDocumentMapper nlWasErgebnisdokumentNachGebietErgebniseingabestatusByGesamtErgebnisDokumentGeneratorDocumentMapper;

  protected AbstractNlWasGesamtErgebnisDokumentNachGebietErgebniseingabestatusDocumentExportMapper() {
    super();
  }

  @Override
  public FileFormat getFileFormat() {
    return new FileFormat(getFileFormatName(), getFileFormatFileType());
  }

  protected FileType getFileFormatFileType() {
    return getDokumentExportMapper().getDefaultTargetFileType();
  }

  @Override
  public boolean supportsTargetFileSigning(AbstractNlExportArtefaktNachSystemExportstatusExportContext context) {
    return false;
  }

  @Override
  public boolean supportsTargetFileHashCode(AbstractNlExportArtefaktNachSystemExportstatusExportContext context) {
    return false;
  }

  @Override
  public List<FileType> getTargetFileTypes(AbstractNlExportArtefaktNachSystemExportstatusExportContext context) {
    return getDokumentExportMapper().getTargetFileTypes();
  }

  @Override
  public String createTargetFileName(AbstractNlExportArtefaktNachSystemExportstatusExportContext context, FileType fileType) {
    return createTargetFileName(context, getTargetSimpleFileName(), fileType);
  }

  protected String getTargetSimpleFileName() {
    return getMessage(getFileFormatName());
  }

  @Override
  protected void serialize(NlExportArtefaktNachSystemExportstatusExportObject exportObject, OutputStream os, NlWasErgebnisArtefaktNachGebietErgebniseingabestatusExportContext context,
      FileKonfiguration fileKonfiguration, boolean closeOutputStream) throws Exception {
    getDokumentExportMapper().serialize(os, context, collectDokumentEntities(context), createDokumentContext(context), closeOutputStream);
  }

  private NlExportArtefaktNachSystemExportstatussDocumentExportMapper<NlWasErgebnisArtefaktNachGebietErgebniseingabestatusExportContext, Ergebnis, GesamtErgebnisDokumentContext> getDokumentExportMapper() {
    return new NlExportArtefaktNachSystemExportstatussDocumentExportMapper<>(getWahlDAO(), getFileFormatName(), dokumentVorlageDAO, getDokumentVorlageNameInfix(),
        getDokumentGeneratorDocumentMapper());
  }

  private GesamtErgebnisDokumentContext createDokumentContext(AbstractNlExportArtefaktNachSystemExportstatusExportContext context) {
    return new GesamtErgebnisDokumentContext(context,
        new ErgebnisExchangeContext(getWahlDAO().attach(context.getWahl()), asList(context.getWurzelgebiet(getGebietDAO())), context.getKandidaturFormatDarstellung()), emptyList());
  }

  private Ergebnis collectDokumentEntities(NlWasErgebnisArtefaktNachGebietErgebniseingabestatusExportContext context) {
    return getErgebnisDAO().attach(context.getErgebnis());
  }

  protected abstract String getDokumentVorlageNameInfix();

  protected NlWasErgebnisdokumentNachGebietErgebniseingabestatusByGesamtErgebnisDokumentGeneratorDocumentMapper getDokumentGeneratorDocumentMapper() {
    return nlWasErgebnisdokumentNachGebietErgebniseingabestatusByGesamtErgebnisDokumentGeneratorDocumentMapper;
  }
}
