
package de.ivu.elect.business.stimmeingabe.control.plausi;

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

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.stimmeingabe.boundary.AbstractErgebnisGueltigerEingangDAO;
import de.ivu.elect.business.stimmeingabe.control.ErgebniseingangEingabeHashCodeGenerator;
import de.ivu.elect.business.stimmeingabe.control.ErgebniseingangEingabeHashCodeGenerator.StimmeingabeIndiziert;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingang;
import de.ivu.elect.business.stimmeingabe.entity.Stimmeingabe;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiKonfiguration;
import de.ivu.elect.jee.faces.Messages;

public abstract class AbstractGruppeStimmenAnzahlenUngleichGruppeStimmenAnzahlenInAnderenErfassungsgebietenPlausi
    extends
      AbstractStimmeingabeAnzahlenUngleichStimmeingabeAnzahlenInAnderenErfassungsgebietenPlausi {

  private final Long anzahlGruppenRelevant;

  private final Collection<Stimmenart> stimmenartenRelevant;

  public AbstractGruppeStimmenAnzahlenUngleichGruppeStimmenAnzahlenInAnderenErfassungsgebietenPlausi(Collection<Stimmenart> stimmenartenRelevant, Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet,
      Ergebniseingang ergebniseingang, AbstractErgebnisGueltigerEingangDAO ergebnisGueltigerEingangDAO, ErgebniseingangEingabeHashCodeGenerator ergebniseingangEingabeHashCodeGenerator,
      StimmeingabePlausiKonfiguration stimmeingabePlausiKonfiguration, Messages messages) {
    super(wahldurchfuehrungsgebiet, ergebniseingang, ergebnisGueltigerEingangDAO, ergebniseingangEingabeHashCodeGenerator, stimmeingabePlausiKonfiguration, messages);

    GruppeStimmenAnzahlenUngleichGruppeStimmenAnzahlenInAnderenErfassungsgebietenPlausiCustomData stimmeingabePlausiKonfigurationCustomData = stimmeingabePlausiKonfiguration
        .getCustomData(GruppeStimmenAnzahlenUngleichGruppeStimmenAnzahlenInAnderenErfassungsgebietenPlausiCustomData.class);

    this.anzahlGruppenRelevant = stimmeingabePlausiKonfigurationCustomData.getAnzahlGruppenRelevant();

    this.stimmenartenRelevant = stimmenartenRelevant;
  }

  protected Long getAnzahlGruppenRelevant() {
    return anzahlGruppenRelevant;
  }

  protected Collection<Stimmenart> getStimmenartenRelevant() {
    return stimmenartenRelevant;
  }

  @Override
  protected String createErgebniseingangEingabeHashCodeSearchPattern(ErgebniseingangEingabeHashCodeGenerator ergebniseingangEingabeHashCodeGenerator,
      Map<Stimmenart, List<StimmeingabeIndiziert>> stimmeingabenPerStimmenart, String wildcardCharacter) {
    return ergebniseingangEingabeHashCodeGenerator.calculateHashCodeSearchPatternByNumberOfGruppen(stimmeingabenPerStimmenart, wildcardCharacter, getAnzahlGruppenRelevant());
  }

  @Override
  protected boolean isStimmeingabenAnzahlenIdentischInternal(Map<Stimmenart, List<StimmeingabeIndiziert>> stimmeingabenPerStimmenart,
      Map<Stimmenart, List<StimmeingabeIndiziert>> stimmeingabenInAnderemErfassungsgebietPerStimmenart) {
    return isGruppeStimmenAnzahlenIdentisch(stimmeingabenPerStimmenart, stimmeingabenInAnderemErfassungsgebietPerStimmenart);
  }

  protected boolean isGruppeStimmenAnzahlenIdentisch(Map<Stimmenart, List<StimmeingabeIndiziert>> stimmeingabenPerStimmenart,
      Map<Stimmenart, List<StimmeingabeIndiziert>> stimmeingabenInAnderemErfassungsgebietPerStimmenart) {
    for (Stimmenart stimmenart : getStimmenartenRelevant()) {
      if (!isGruppeStimmenAnzahlenIdentisch(getAnzahlGruppenRelevant(), stimmenart, stimmeingabenPerStimmenart, stimmeingabenInAnderemErfassungsgebietPerStimmenart)) {
        return false;
      }
    }

    return !getStimmenartenRelevant().isEmpty();
  }

  @Override
  protected List<Object> getStimmeingabefehlerBeschreibungParameters(Stimmeingabe stimmeingabe) {
    List<Object> result = new ArrayList<>(super.getStimmeingabefehlerBeschreibungParameters(stimmeingabe));
    result.add(getAnzahlGruppenRelevant());

    return result;
  }

  @Override
  public String getStimmeingabefehlerBeschreibung(Stimmeingabe stimmeingabe, Number anzahlSoll, Number anzahlSollDifferenz) {
    return getStimmeingabefehlerBeschreibung(stimmeingabe, getAnzahlGruppenRelevant(), anzahlSollDifferenz, null);
  }
}
