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.DateiImportDAO;
import de.ivu.elect.business.datei.entity.Datei;
import de.ivu.elect.business.datei.entity.DateiImport;
import de.ivu.elect.business.exchange.entity.DateiImportArt;
import de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte;
import de.ivu.elect.business.konfiguration.entity.KonfigurationLoader;

public class DateiImportFileCleanupStrategie implements FileCleanupStrategy {

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

  @Inject
  private transient DateiImportDAO dateiImportDAO;

  @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<DateiImport> zuLoeschen) {
    for (DateiImport dateiImport : zuLoeschen) {
      LOG.info("Bereinige: " + dateiImport.getDateiArt() + ", wahltermin: " + dateiImport.getDatei().getWahltermin() + ", wahl: " + dateiImport.getDatei()
          .getWahl());
      Datei datei = dateiImport.getDatei();
      dateiImportDAO.remove(dateiImport);
      dateiDAO.remove(datei);
    }
  }

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

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

    Map<DateiImportCleanupSchluessel, List<DateiImport>> importNachSchluessel = dateiImportDAO.findByAll().stream()
        .collect(Collectors.groupingBy(DateiImportCleanupSchluessel::new));

    for (Map.Entry<DateiImportCleanupSchluessel, List<DateiImport>> entry : importNachSchluessel.entrySet()) {
      DateiImportArt dateiImportArt = entry.getKey().getDateiImportArt();
      List<DateiImport> values = entry.getValue();

      Integer maxFuerArt = dateiImportArt.overrideMaxEintraege(max);
      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 DateiImportFileCleanupStrategie.class.getName();
  }
}
