
package de.ivu.elect.business.stimmeingabe.boundary;

import static de.ivu.elect.business.konfiguration.entity.MandantKonfigurationWerte.STIMMEINGABE_ABLAGEVERZEICHNIS;
import static de.ivu.elect.business.konfiguration.entity.MandantKonfigurationWerte.STIMMEINGABE_DATEIEXPORT_AKTIVIERT;

import javax.ejb.Stateless;
import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.datei.boundary.DateiExportDAO;
import de.ivu.elect.business.datei.entity.Datei;
import de.ivu.elect.business.datei.entity.DateiExport;
import de.ivu.elect.business.datei.entity.DateiExportPK;
import de.ivu.elect.business.datei.entity.DateiFileNames;
import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.exchange.control.AbstractExporter;
import de.ivu.elect.business.exchange.control.ExportExchange;
import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.exchange.entity.DateiExportArt;
import de.ivu.elect.business.konfiguration.control.StreamCreator;
import de.ivu.elect.business.konfiguration.entity.KonfigurationLoader;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.replikation.boundary.ReplikationErzeugen;
import de.ivu.elect.business.stimmeingabe.control.ErgebniseingangExportContext;
import de.ivu.elect.business.stimmeingabe.control.ErgebniseingangExportExchange;
import de.ivu.elect.business.stimmeingabe.control.ErgebniseingangExportStreamCreator;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeStimmenuebernahmeExporter;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingang;
import de.ivu.elect.business.system.boundary.SystemLogWriter;
import de.ivu.elect.business.system.entity.SystemLogQuelle;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlParameterLoader;
import de.ivu.elect.business.wahl.entity.WahlParameterWerte;
import de.ivu.elect.business.wahl.entity.Wahltermin;

/**
 * Ist für das AUTOMATISCHE Speichern im Hintergrund zuständig. Wird NICHT explizit vom Benutzer angestoßen!
 */
@Stateless
public class ErgebniseingangExporter extends AbstractExporter<Ergebniseingang, ErgebniseingangExportContext> {

  private static final Logger LOG = LoggerFactory.getLogger(ErgebniseingangExporter.class);

  public static final String FILE_FORMAT_NAME = "file.format.ergebniseingang";

  public static final FileFormat FILE_FORMAT = new FileFormat(FILE_FORMAT_NAME, FileType.ZIP);

  public static final DateiExportArt DATEI_EXPORT_ART = DateiExportArt.STIMMEINGABE_EXPORT;

  @Inject
  private transient ErgebniseingangExportExchange ergebniseingangExportExchange;

  @Inject
  private transient DateiExportDAO dateiExportDAO;

  @Inject
  private transient KonfigurationLoader konfigurationLoader;

  @Inject
  private transient ReplikationErzeugen replikationErzeugen;

  @Inject
  private transient WahlParameterLoader wahlParameterLoader;

  @Inject
  private transient StimmeingabeStimmenuebernahmeExporter stimmeingabeStimmenuebernahmeExporter;

  @Inject
  private transient SystemLogWriter systemLogWriter;

  public ErgebniseingangExporter() {
    super();
  }

  @Override
  protected DateiExportArt getDateiExportArt() {
    return DATEI_EXPORT_ART;
  }

  public void export(Ergebniseingang ergebniseingang) {
    // Ergebniseingang immer Replizieren
    replikationErzeugen.replikationErgebniseingang(ergebniseingang);

    // Stimmenübernahme in eigenes Verzeichnis exportieren
    stimmeingabeStimmenuebernahmeExporter.export(ergebniseingang);

    // In Datei schreiben, nur wenn konfiguriert
    if (konfigurationLoader.resolveBooleanValue(ergebniseingang.getMandant(), STIMMEINGABE_DATEIEXPORT_AKTIVIERT)
        && StringUtils.isNotBlank(konfigurationLoader.resolveStringValue(ergebniseingang.getMandant(), STIMMEINGABE_ABLAGEVERZEICHNIS))) {
      export(ergebniseingang, FILE_FORMAT);
    } else {
      LOG.debug("Stimmeingaben werden nicht in Datei geschrieben, da per Systemparameter deaktiviert");
    }
  }

  private void export(Ergebniseingang ergebniseingang, FileFormat fileFormat) {
    Wahl wahl = ergebniseingang.getWahldurchfuehrungsgebiet().getWahl();
    ErgebniseingangExportContext context = createContext(ergebniseingang, wahl);

    export(fileFormat, wahl, context);
  }

  public void export(FileFormat fileFormat, Wahl wahl, ErgebniseingangExportContext context) {
    DateiExportPK pk = super.export(fileFormat, context, wahl.getMandant(), wahl, wahl.getWahltermin());
    // ELECT-2465 Löschen, damit der DateiExport nicht mehr im Export-Search auftaucht
    dateiExportDAO.remove(dateiExportDAO.findByPrimaryKey(pk));
  }

  public void exportNoException(FileFormat fileFormat, Wahl wahl, ErgebniseingangExportContext context, SystemLogQuelle systemLogQuelle) {

    try {
      export(fileFormat, wahl, context);
    } catch (Exception e) {
      systemLogWriter.writeErrorLogMessageFuerMandant(wahl, getMessage("ergebnis.eingang.export.fehler"), e, systemLogQuelle);
    }
  }

  public ErgebniseingangExportContext createContext(Ergebniseingang ergebniseingang, Wahl wahl) {
    ErgebniseingangExportContext result = new ErgebniseingangExportContext(ergebniseingang);

    // ELECT-5871
    String wahlkurzname = wahlParameterLoader.resolveStringValue(wahl, WahlParameterWerte.BUNDESWAHLLEITER_EXPORT_WAHL_KURZNAME);

    result.setWahlkurzname(wahlkurzname);

    return result;
  }

  @Override
  protected ExportExchange<Ergebniseingang, ErgebniseingangExportContext> getExchange() {
    return ergebniseingangExportExchange;
  }

  @Override
  protected Ergebniseingang getExportObject(ErgebniseingangExportContext context) {
    throw new UnsupportedOperationException();
  }

  @Override
  protected Ergebniseingang getExportObject(ErgebniseingangExportContext context, FileFormat fileFormat, DateiExport dateiExport) {
    return getErgebniseingang(context);
  }

  @Override
  protected DateiExport createDateiExport(FileFormat fileFormat, DateiFileNames dateiFileNames, ErgebniseingangExportContext context, Mandant mandant, Wahl wahl, Wahltermin wahltermin) {
    Ergebniseingang ergebniseingang = getErgebniseingang(context);

    DateiExport dateiExport = super.createDateiExport(fileFormat, dateiFileNames, context, mandant, wahl, wahltermin);

    Datei datei = dateiExport.getDatei();
    datei.setDateiname(ergebniseingangExportExchange.getDateiname(fileFormat, context, ergebniseingang));
    datei.setOriginalDateiname(datei.getDateiname());

    return dateiExport;
  }

  private Ergebniseingang getErgebniseingang(ErgebniseingangExportContext context) {
    return context.getErgebniseingang();
  }

  @Override
  protected StreamCreator getStreamCreator(FileFormat fileFormat, ErgebniseingangExportContext context) {
    return new ErgebniseingangExportStreamCreator(getExportDirectory(fileFormat, context));
  }

  private String getExportDirectory(FileFormat fileFormat, ErgebniseingangExportContext context) {
    return ergebniseingangExportExchange.getExportDirectory(fileFormat, context, getErgebniseingang(context));
  }
}
