
package de.ivu.elect.business.ergebnis.boundary;

import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.emptyList;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.wahl.boundary.WahlartTemplate;
import de.ivu.elect.business.wahl.entity.CommonWahlart;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisart;

public class ErgebnisdokumentTypPerWahlartResolver {

  public ErgebnisdokumentTypPerWahlartResolver() {
    super();
  }

  public boolean isErgebnisartSupported(Ergebnis ergebnis, ErgebnisdokumentTyp ergebnisdokumentTyp) {
    return ergebnis != null && isErgebnisartSupported(ergebnis.getWahl(), ergebnisdokumentTyp, ergebnis.getErgebnisart());
  }

  public boolean isErgebnisartSupported(Wahl wahl, ErgebnisdokumentTyp ergebnisdokumentTyp, WahlartErgebnisart ergebnisart) {
    if (wahl != null) {
      Collection<WahlartErgebnisart> ergebnisartenSupported = collectErgebnisartenSupported(wahl, ergebnisdokumentTyp);

      return !ergebnisartenSupported.isEmpty() && ergebnisartenSupported.stream().anyMatch(one -> one.equalsErgebnisart(ergebnisart));
    }

    return false;
  }

  protected Collection<WahlartErgebnisart> collectErgebnisartenSupported(Wahl wahl, ErgebnisdokumentTyp ergebnisdokumentTyp) {
    if (matchesErgebnisdokumentTyp(ergebnisdokumentTyp, DefaultErgebnisdokumentTyp.ERGEBNIS_ERSTE_SCHNELLMELDUNG)) {
      return asList(Ergebnisart.VORLAEUFIG);
    }

    if (matchesErgebnisdokumentTyp(ergebnisdokumentTyp, DefaultErgebnisdokumentTyp.ERGEBNIS_WAHLNIEDERSCHRIFT)) {
      return asList(Ergebnisart.ENDGUELTIG);
    }

    if (matchesErgebnisdokumentTyp(ergebnisdokumentTyp, DefaultErgebnisdokumentTyp.ERGEBNIS_KANDIDATUREN)) {
      return asList(Ergebnisart.ENDGUELTIG);
    }

    if (matchesErgebnisdokumentTyp(ergebnisdokumentTyp, DefaultErgebnisdokumentTyp.ERGEBNIS_GESAMTERGEBNIS)) {
      List<WahlartErgebnisart> result = new ArrayList<>();
      result.add(Ergebnisart.ENDGUELTIG);

      if (matchesWahlart(wahl, CommonWahlart.BUNDESTAGSWAHL, CommonWahlart.EUROPAWAHL, /* ELECT-12928 */ CommonWahlart.BUERGERMEISTERWAHL, CommonWahlart.VOLKSENTSCHEID,
          /* ELECT-12375 */ CommonWahlart.BUERGERENTSCHEID)) {
        result.add(Ergebnisart.VORLAEUFIG);
      }

      return result;
    }

    if (matchesErgebnisdokumentTyp(ergebnisdokumentTyp, DefaultErgebnisdokumentTyp.ERGEBNIS_ZAEHLLISTE)) {
      return asList(Ergebnisart.VORLAEUFIG, Ergebnisart.ENDGUELTIG);
    }

    if (matchesErgebnisdokumentTyp(ergebnisdokumentTyp, DefaultErgebnisdokumentTyp.BEKANNTMACHUNG_WAHLERGEBNIS)) {
      return asList(Ergebnisart.VORLAEUFIG, Ergebnisart.ENDGUELTIG); // ELECT-9460
    }

    if (matchesErgebnisdokumentTyp(ergebnisdokumentTyp, DefaultErgebnisdokumentTyp.WAHLAUSSCHUSS_NIEDERSCHRIFT)) {
      return asList(Ergebnisart.ENDGUELTIG);
    }

    return emptyList();
  }

  protected boolean matchesErgebnisdokumentTyp(ErgebnisdokumentTyp one, ErgebnisdokumentTyp another) {
    return one.name().equals(another.name());
  }

  protected boolean matchesWahlart(Wahl wahl, WahlartTemplate... wahlartTemplates) {
    return stream(wahlartTemplates).anyMatch(wahlartTemplate -> wahlartTemplate.equalsWahlart(wahl));
  }
}
