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

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.util.FileUtil;


import static java.util.Objects.nonNull;

public class PapierkorbAufbewahrungAbgelaufenCleaner extends AbstractCleaner<List<File>> implements FileCleaner<List<File>> {

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

  public static final Set<String> DENYLIST = new HashSet<>();

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

  @Override
  public void bereinige(File verzeichnis, FileCleanerBucket<List<File>> bucket) throws Exception {
    for (var file : bucket.getBucket()) {
      try {
        Files.deleteIfExists(file.toPath());
        LOG.info("Datei '" + file.getAbsolutePath() + "' aus dem Papierkorb gelöscht.");
      } catch (Exception e) {
        DENYLIST.add(file.getAbsolutePath()); // WASDE-2228
        LOG.warn("Fehler beim Löschen der Datei '" + file.getAbsolutePath() + "' aus dem Papierkorb.", e);
      }
    }
  }

  @Override
  public List<FileCleanerBucket<List<File>>> getBuckets(File verzeichnis) throws Exception {
    var filesAbgelaufen = getFilesAbgelaufen(verzeichnis);
    if (filesAbgelaufen.isEmpty()) {
      return Collections.emptyList();
    }
    return Collections.singletonList(new FileCleanerBucket<>(filesAbgelaufen));
  }

  private List<File> getFilesAbgelaufen(File verzeichnis) {
    var daysInRecycleBin = getDaysInRecycleBin();
    if (nonNull(daysInRecycleBin)) {
      var millisToDeleteFile = getMillisToDeleteFile(daysInRecycleBin);
      var recycleBinVerzeichnis = getRecyclebin(verzeichnis);
      if (recycleBinVerzeichnis.isDirectory()) {
        try {
          return FileUtil.listFilesInDirectoryFast(recycleBinVerzeichnis, true).stream().filter(file -> {
            try {
              return !DENYLIST.contains(file.getAbsolutePath())/*WASDE-2228*/ && file.isFile()/*WASDE-2228*/ && file.lastModified() < millisToDeleteFile;
            } catch (SecurityException e) {
              LOG.warn("Fehler beim Prüfen der Datei '" + file.getAbsolutePath() + "' im Papierkorb.");
              DENYLIST.add(file.getAbsolutePath()); // WASDE-2228
            }
            return false;
          }).collect(Collectors.toList());
        } catch (IOException e) {
          throw new RuntimeException(e.getMessage(), e);
        }
      }
    }
    return Collections.emptyList();
  }

  private long getMillisToDeleteFile(Integer daysInRecycleBin) {
    return DateUtils.addDays(new Date(), -daysInRecycleBin).getTime();
  }
}
