
package de.ivu.elect.dokumente.konverter;

import static java.util.stream.Collectors.toList;

import java.util.List;
import java.util.function.BiPredicate;

import javax.annotation.Nullable;

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.dokumente.boundary.AbstractDokumentVorlageDAO;
import de.ivu.elect.business.dokumente.control.DokumentVorlageByImportiertAmComparator;
import de.ivu.elect.business.dokumente.entity.DokumentVorlage;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.wahl.entity.Wahl;

public class DokumentGeneratorDocumentMapperDokumentVorlagen {

  private final Wahl wahl;

  private final AbstractDokumentVorlageDAO dokumentVorlageDAO;

  private final DokumentVorlageArt dokumentVorlageArt;

  private final FileType dokumentVorlageFileType;

  private final String dokumentVorlageName;

  private final String dokumentVorlageNameResourcesArchive;

  private final BiPredicate<String, String> dokumentVorlageNameMatcher;

  public DokumentGeneratorDocumentMapperDokumentVorlagen(Wahl wahl, AbstractDokumentVorlageDAO dokumentVorlageDAO, DokumentVorlageArt dokumentVorlageArt, FileType dokumentVorlageFileType,
      String dokumentVorlageName) {
    this(wahl, dokumentVorlageDAO, dokumentVorlageArt, dokumentVorlageFileType, dokumentVorlageName, StringUtils::containsIgnoreCase);
  }

  public DokumentGeneratorDocumentMapperDokumentVorlagen(Wahl wahl, AbstractDokumentVorlageDAO dokumentVorlageDAO, DokumentVorlageArt dokumentVorlageArt, FileType dokumentVorlageFileType,
      String dokumentVorlageName, BiPredicate<String, String> dokumentVorlageNameMatcher) {
    super();

    this.wahl = wahl;

    this.dokumentVorlageDAO = dokumentVorlageDAO;

    this.dokumentVorlageArt = dokumentVorlageArt;

    this.dokumentVorlageFileType = dokumentVorlageFileType;

    this.dokumentVorlageName = dokumentVorlageName;
    this.dokumentVorlageNameResourcesArchive = dokumentVorlageName + "-resources";
    this.dokumentVorlageNameMatcher = dokumentVorlageNameMatcher;
  }

  @Nullable
  public DokumentVorlage getDokumentVorlage() {
    return getDokumentVorlage(null);
  }

  @Nullable
  public DokumentVorlage getDokumentVorlage(@Nullable DokumentVorlage template) {
    DokumentVorlage result = template;

    if (result == null) {
      result = findDokumentVorlage(dokumentVorlageFileType, dokumentVorlageName);
    }

    return dokumentVorlageDAO.attach(result);
  }

  @Nullable
  public DokumentVorlage getDokumentVorlageResourcesArchive() {
    return findDokumentVorlage(FileType.DVZ, dokumentVorlageNameResourcesArchive);
  }

  @Nullable
  private DokumentVorlage findDokumentVorlage(FileType fileType, String dokumentVorlageName) {
    List<DokumentVorlage> dokumentVorlagen = dokumentVorlageDAO.findByWahlAndArtOrderByName(wahl, dokumentVorlageArt).stream() //
        .filter(dokumentVorlage -> dokumentVorlage.hasFileType(fileType)) //
        .filter(dokumentVorlage -> dokumentVorlage.matchesName(dokumentVorlageName, dokumentVorlageNameMatcher)) //
        .sorted(DokumentVorlageByImportiertAmComparator.DESCENDING) //
        .collect(toList());

    if (!dokumentVorlagen.isEmpty()) {
      return dokumentVorlagen.get(0);
    }

    return null;
  }
}
