
package de.ivu.elect.business.stimmeingabe.control.background;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import javax.annotation.Nonnull;
import javax.ejb.Stateless;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.datei.entity.DateiImportBerichtCustomData;
import de.ivu.elect.business.exchange.control.DateienImportierenBackgroundService;
import de.ivu.elect.business.exchange.entity.DateiImportArt;
import de.ivu.elect.business.exchange.entity.DateienImportierenBackgroundServiceContext;
import de.ivu.elect.business.exchange.entity.DateienImportierenBackgroundServiceImportContext;
import de.ivu.elect.business.mandant.entity.EntityPKMitMandant;
import de.ivu.elect.business.replikation.boundary.ReplikationBusinessStatus;
import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeImporter;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeImportContext;
import de.ivu.elect.business.system.control.AbstractWahlMultipleCronTimerAsync;
import de.ivu.elect.business.system.entity.SystemLogQuelle;
import de.ivu.elect.business.wahl.entity.WahlPK;
import de.ivu.elect.business.wahl.entity.WahlParameterWerte;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;
import de.ivu.elect.jee.exchange.ImportOptions;


import static de.ivu.elect.business.wahl.entity.WahlParameterWerte.STIMMEINGABEN_CUSTOM_FORMAT_IMPORT_ERFOLGREICH_VERZEICHNIS;
import static de.ivu.elect.business.wahl.entity.WahlParameterWerte.STIMMEINGABEN_CUSTOM_FORMAT_IMPORT_FEHLER_VERZEICHNIS;
import static de.ivu.elect.business.wahl.entity.WahlParameterWerte.STIMMEINGABEN_CUSTOM_FORMAT_IMPORT_VERZEICHNIS;

@Stateless
public class StimmeingabeCustomFormatImportAsync extends AbstractWahlMultipleCronTimerAsync {

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

  public static final WahlParameterWerte IMPORT_VERZEICHNIS = STIMMEINGABEN_CUSTOM_FORMAT_IMPORT_VERZEICHNIS;

  public static final WahlParameterWerte FEHLER_VERZEICHNIS = STIMMEINGABEN_CUSTOM_FORMAT_IMPORT_FEHLER_VERZEICHNIS;

  public static final WahlParameterWerte ERFOLG_VERZEICHNIS = STIMMEINGABEN_CUSTOM_FORMAT_IMPORT_ERFOLGREICH_VERZEICHNIS;

  @Inject
  private transient DateienImportierenBackgroundService dateienImportierenBackgroundService;

  @Inject
  private transient Instance<StimmeingabeCustomFormatImportFormatResolver> formatResolvers;

  @Inject
  private transient ReplikationBusinessStatus replikationBusinessStatus;

  @Inject
  private transient StimmeingabeCustomFormatImportAsyncAktiv stimmeingabeCustomFormatImportAsyncAktiv;

  public StimmeingabeCustomFormatImportAsync() {
    super();
  }

  @Override
  public SystemLogQuelle getSystemLogQuelle() {
    return SystemLogQuelle.STIMMEINGABE_DATEIEN_IMPORTER;
  }

  @Override
  protected void handleWahl(WahlPK wahlPK) throws Exception {
    LOG.info("StimmeingabeCustomFormatImportAsync.handle " + "wahlPK = [" + wahlPK + "]");

    if (getAktiveFormatResolvers().isEmpty()) {
      LOG.info("StimmeingabeCustomFormatImportAsync.handle: Keine Format-Resolver, kein Import");
    } else {

      if (stimmeingabeCustomFormatImportAsyncAktiv.isAktiviert(wahlPK)) {
        while (dateienImportierenBackgroundService.importiere(wahlPK, createContext(EntityPKMitMandant.from(wahlPK)))) {
          LOG.info("StimmeingabeCustomFormatImportAsync.handle - weiterer Aufruf");
        }
      } else {
        LOG.info("StimmeingabeCustomFormatImportAsync.handle: deaktiviert: " + wahlPK);
      }
    }

    LOG.info("StimmeingabeCustomFormatImportAsync.handle " + "wahlPK = [" + wahlPK + "]" + " - done");
  }

  private List<StimmeingabeCustomFormatImportFormatResolver> getAktiveFormatResolvers() {
    List<StimmeingabeCustomFormatImportFormatResolver> result = new ArrayList<>();

    boolean slave = replikationBusinessStatus.isSlave();

    for (StimmeingabeCustomFormatImportFormatResolver formatResolver : formatResolvers) {
      // WASDE-1153
      if (!slave || formatResolver.isReplikationSlaveSupported()) {
        result.add(formatResolver);
      }
    }

    return result;
  }

  protected DateienImportierenBackgroundServiceContext createContext(EntityPKMitMandant entityPKMitMandant) {
    return new DateienImportierenBackgroundServiceContext(IMPORT_VERZEICHNIS, ERFOLG_VERZEICHNIS, FEHLER_VERZEICHNIS, getSystemLogQuelle(), createImportContext(entityPKMitMandant),
        getDateiReihenfolge());
  }

  @Nonnull
  protected Function<File, File> getDateiReihenfolge() {
    return getAktiveFormatResolvers().stream()
        .filter(formatResolver -> formatResolver.getDateiReihenfolge() != null)
        .findFirst()
        .map(StimmeingabeCustomFormatImportFormatResolver::getDateiReihenfolge)
        .orElse(DateienImportierenBackgroundServiceContext::bestimmeNaechsteDateiAlphabetischSortiert);
  }

  protected DateienImportierenBackgroundServiceImportContext createImportContext(EntityPKMitMandant entityPKMitMandant) {
    return new DateienImportierenBackgroundServiceImportContext(entityPKMitMandant, StimmeingabeImporter.class, getAktiveFormatResolvers(), DateiImportArt.STIMMEINGABE_IMPORT,
        (w, f) -> new StimmeingabeImportContext(w.castTo(Wahldurchfuehrung.class).getEntity()),
        ImportOptions.NEUE_DATEN_ANLEGEN_BESTEHENDE_DATEN_UNVERAENDERT_LASSEN, new DateiImportBerichtCustomData());
  }

  @Override
  protected EntityPKMitMandant bestimmeMandantAusPayload(WahlPK wahlPK) {
    return bestimmeMandant(wahlPK);
  }

  @Override
  public Logger getLog() {
    return LOG;
  }
}
