package de.ivu.elect.business.internet.entity;

import de.ivu.elect.business.gebietsbaum.control.GebietByBreadthFirstComparator;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.Gebietsart;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahlart;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;

import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public class InternetSeitePropertyContext {

  private static final long MAX_GEBIETE_SIZE = 4_000; // willkürlich, unter 5000 wegen max_parameter

  private final Messages messages;

  private final Wahl wahl;

  private final InternetSeiteTyp internetSeiteTyp;

  private final GebietNummerFormatter gebietNummerFormatter;

  private final Supplier<List<Gebiet>> gebiete;

  private final Supplier<List<Wahlart>> alleWahlarten;

  private final Supplier<List<Gebietsart>> alleGebietsarten;

  public InternetSeitePropertyContext(Messages messages, Wahl wahl, InternetSeiteTyp internetSeiteTyp, GebietNummerFormatter gebietNummerFormatter, Supplier<List<Gebiet>> gebiete, Supplier<List<Wahlart>> alleWahlarten, Supplier<List<Gebietsart>> alleGebietsarten) {
    this.messages = messages;
    this.wahl = wahl;
    this.internetSeiteTyp = internetSeiteTyp;
    this.gebietNummerFormatter = gebietNummerFormatter;
    this.gebiete = gebiete;
    this.alleWahlarten = alleWahlarten;
    this.alleGebietsarten = alleGebietsarten;
  }

  public Messages getMessages() {
    return messages;
  }

  public InternetSeiteTyp getInternetSeiteTyp() {
    return internetSeiteTyp;
  }

  public GebietNummerFormatter getGebietNummerFormatter() {
    return gebietNummerFormatter;
  }

  public Wahl getWahl() {
    return wahl;
  }

  public Supplier<List<Gebiet>> getGebieteLimitiert() {
    return () -> {
      List<Gebiet> gebieteResult = gebiete.get();
      if (gebieteResult == null) {
        return Collections.emptyList();
      }
      //ELECT-9232
      if (gebieteResult.size() > MAX_GEBIETE_SIZE) {
        return gebieteResult.stream().sorted(new GebietByBreadthFirstComparator()).limit(MAX_GEBIETE_SIZE).collect(Collectors.toList());
      }
      return gebieteResult;
    };
  }

  public Supplier<List<Wahlart>> getAlleWahlarten() {
    return alleWahlarten;
  }

  public Supplier<List<Gebietsart>> getAlleGebietsarten() {
    return alleGebietsarten;
  }
}

