package de.ivu.elect.business.system.control.files.strategies;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Nullable;
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.DateiDAO;
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.exchange.entity.DateiExportArt;
import de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte;
import de.ivu.elect.business.konfiguration.entity.KonfigurationLoader;

public class DateiExportFileCleanupStrategie implements FileCleanupStrategy {

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

  @Inject
  private transient DateiExportDAO dateiExportDAO;

  @Inject
  private transient DateiDAO dateiDAO;

  @Inject
  private transient KonfigurationLoader konfigurationLoader;

  @Override
  public boolean isDirtyFilePresent(File verzeichnis) throws Exception {
    return !finde().isEmpty();
  }

  @Override
  public void bereinige(File verzeichnis) throws Exception {
    loesche(finde());
  }

  private void loesche(List<DateiExport> zuLoeschen) {
    for (DateiExport dateiExport : zuLoeschen) {
      LOG.info("Bereinige: " + dateiExport.getDateiArt() + ", wahltermin: " + dateiExport.getDatei().getWahltermin() + ", wahl: " + dateiExport.getDatei()
          .getWahl());
      Datei datei = dateiExport.getDatei();
      dateiExportDAO.remove(dateiExport);
      dateiDAO.remove(datei);
    }
  }

  private List<DateiExport> finde() {
    Integer max = parse(konfigurationLoader.resolveStringValue(ElectKonfigurationWerte.ELECT_COMMON_DATEI_CLEANUP_MAX_EXPORT_COUNT));
    if (max == null) {
      return Collections.emptyList(); // nicht gesetzt
    }

    List<DateiExport> result = new ArrayList<>();

    Map<DateiExportCleanupSchluessel, List<DateiExport>> importNachSchluessel = dateiExportDAO.findByAll().stream()
        .collect(Collectors.groupingBy(DateiExportCleanupSchluessel::new));

    for (Map.Entry<DateiExportCleanupSchluessel, List<DateiExport>> entry : importNachSchluessel.entrySet()) {
      DateiExportArt dateiExportArt = entry.getKey().getDateiExportArt();
      List<DateiExport> values = entry.getValue();

      Integer maxFuerArt = dateiExportArt.overrideMaxEintraege(max, konfigurationLoader);
      if (maxFuerArt != null && values.size() > maxFuerArt) {

        values.sort((v, u) -> u.getDatei().getErstellungszeitpunkt().compareTo(v.getDatei().getErstellungszeitpunkt())); // neuste zuerst

        for (int pos = maxFuerArt; pos < values.size(); pos++) {
          result.add(values.get(pos));
        }
      }

    }

    return result;
  }

  @Nullable
  private Integer parse(String value) {
    if (StringUtils.isBlank(value)) {
      return null;
    }
    try {
      return Integer.parseInt(value);
    } catch (Exception e) {
      return null;
    }

  }

  @Override
  public String getName() {
    return DateiExportFileCleanupStrategie.class.getName();
  }
}
