
package de.ivu.elect.business.gruppeimgebiet.control;

import java.io.Serializable;
import java.util.Comparator;
import java.util.Set;

import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.wahlvorschlag.control.WahlvorschlagByKennwortComparator;
import de.ivu.elect.business.wahlvorschlag.control.WahlvorschlagByPrivilegierungsTypComparator;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;

public class GruppeImGebietReihenfolgeVorsortierenComparator implements Comparator<GruppeImGebiet>, Serializable {

  private static final long serialVersionUID = 1L;

  protected static final GruppeImGebietByVorgegebenePositionComparator VORGEGEBENE_POSITION_COMPARATOR = new GruppeImGebietByVorgegebenePositionComparator();

  protected static final GruppeImGebietByRelativePositionComparator RELATIVE_POSITION_COMPARATOR = new GruppeImGebietByRelativePositionComparator();

  protected static final WahlvorschlagByPrivilegierungsTypComparator PRIVILEGIERUNGS_TYP_COMPARATOR = new WahlvorschlagByPrivilegierungsTypComparator();

  protected static final WahlvorschlagByKennwortComparator KENNWORT_COMPARATOR = new WahlvorschlagByKennwortComparator();

  protected static final GruppeImGebietByNameAufGebietComparator NAME_AUF_GEBIET_COMPARATOR = new GruppeImGebietByNameAufGebietComparator();

  protected GruppeImGebietReihenfolgeVorsortierenComparator() {
    super();
  }

  @Override
  public int compare(GruppeImGebiet gig1, GruppeImGebiet gig2) {

    int result = 0;

    // Wenn relative Position bereits gesezt, dann höchste PRIO, weil...???
    if (result == 0) {
      result = RELATIVE_POSITION_COMPARATOR.compare(gig1, gig2);
    }

    if (result == 0) {
      GruppeImGebiet gig1Uebergeordnet = gig1.getUebergeordneteGruppeImGebiet();
      GruppeImGebiet gig2Uebergeordnet = gig2.getUebergeordneteGruppeImGebiet();
      if (gig1Uebergeordnet != null && gig2Uebergeordnet != null) {
        result = RELATIVE_POSITION_COMPARATOR.compare(gig1Uebergeordnet, gig2Uebergeordnet);
      }
    }

    //  fixierte Position
    if (result == 0) {
      result = VORGEGEBENE_POSITION_COMPARATOR.compare(gig1, gig2);
    }

    // ELECT-8626 Gruppenposition
    if (result == 0) {
      result = compareGruppenPosition(gig1, gig2);
    }


    if (result == 0) {
      Set<Wahlvorschlag> wahlvorschlaege1 = gig1.getWahlvorschlaege();
      Set<Wahlvorschlag> wahlvorschlaege2 = gig2.getWahlvorschlaege();

      if (!wahlvorschlaege1.isEmpty() && wahlvorschlaege2.isEmpty()) {
        return -1;
      }

      if (wahlvorschlaege1.isEmpty() && !wahlvorschlaege2.isEmpty()) {
        return 1;
      }

      if (!wahlvorschlaege1.isEmpty() && !wahlvorschlaege2.isEmpty()) {
        // TODO: Was passiert bei mehr als einem Wahlvorschlag im Gebiet?
        Wahlvorschlag wvs1 = wahlvorschlaege1.iterator().next();
        Wahlvorschlag wvs2 = wahlvorschlaege2.iterator().next();

        // Dann Privilegierungstyp
        result = PRIVILEGIERUNGS_TYP_COMPARATOR.compare(wvs1, wvs2);

        // Dann Kennwort
        if (result == 0) {
          result = KENNWORT_COMPARATOR.compare(wvs1, wvs2);
        }
      }
    }


    // NameAufGebiet, fallback
    if (result == 0) {
      result = NAME_AUF_GEBIET_COMPARATOR.compare(gig1, gig2);
    }

    return result;
  }

  private int compareGruppenPosition(GruppeImGebiet gig1, GruppeImGebiet gig2) {
    return getPositionVonGruppe(gig1).compareTo(getPositionVonGruppe(gig2));
  }

  private Long getPositionVonGruppe(GruppeImGebiet gig) {
    Long gruppenPosition = Long.MAX_VALUE;
    if (gig != null && gig.getGruppe() != null && gig.getGruppe().getVorgegebenePosition() != null) {
      gruppenPosition = gig.getGruppe().getVorgegebenePosition();
    }
    return gruppenPosition;
  }
}
