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

import static java.util.Arrays.asList;

import javax.inject.Inject;

import de.ivu.elect.business.gruppe.boundary.GruppeDAO;
import de.ivu.elect.business.gruppe.entity.AbstractGruppe;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.wahl.boundary.WahlDAO;
import de.ivu.elect.business.wahl.entity.Wahl;

public class PolitischeGruppeCreate extends AbstractPolitischeGruppeCreate {

  @Inject
  protected transient WahlDAO wahlDAO;

  @Inject
  protected transient GruppeDAO gruppeDAO;

  public PolitischeGruppeCreate() {
    super();
  }

  @Override
  public void save(PolitischeGruppe politischeGruppe) {
    save(politischeGruppe.getWahl(), politischeGruppe);
  }

  private void save(Wahl wahlNotAttached, PolitischeGruppe politischeGruppe) {
    Wahl wahl = attach(wahlNotAttached);
    normalisiereSchluessel(politischeGruppe);

    validate(politischeGruppe);

    politischeGruppe.setWahl(wahl);

    if (politischeGruppe.getRelativePosition() == null && politischeGruppe.getSchluessel() != null) {
      // versuche den Schlüssel als relative Position zu verwenden
      try {
        politischeGruppe.setRelativePosition(Long.parseLong(politischeGruppe.getSchluessel()));
      } catch (NumberFormatException nfe) {
        // egal
      }
    }

    AbstractGruppe.relativePositionSetzenWennNoetig(asList(politischeGruppe), gruppeDAO.findByWahl(wahl));

    // default-Werte setzen, falls nicht vorhanden
    if (politischeGruppe.getInPraesentation() == null) {
      politischeGruppe.setInPraesentation(true);
    }
    if (politischeGruppe.getMinderheit() == null) {
      politischeGruppe.setMinderheit(false);
    }
    if (politischeGruppe.getPrivilegiert() == null) {
      politischeGruppe.setPrivilegiert(false);
    }

    if (politischeGruppe.getKurzname() == null) {
      politischeGruppe.setKurzname(politischeGruppe.getSchluessel());
    }
    if (politischeGruppe.getName() == null) {
      politischeGruppe.setName(politischeGruppe.getKurzname());
    }

    super.save(politischeGruppe);
  }

  private void normalisiereSchluessel(PolitischeGruppe politischeGruppe) {
    String schluesselNormalisiert = PolitischeGruppeSchluesselNormalisierer.normalisiere(politischeGruppe.getSchluessel());
    politischeGruppe.setSchluessel(schluesselNormalisiert);
  }

  protected void validate(PolitischeGruppe politischeGruppe) {
    assertKeineSystemGruppe(politischeGruppe);
    assertUnique(politischeGruppe);
  }

  private void assertKeineSystemGruppe(PolitischeGruppe politischeGruppe) {
    if (politischeGruppe.isSystemGruppe()) {
      throw new IllegalStateException("Eine politische Gruppe [gruppe = <" + politischeGruppe + ">] darf keine System-Gruppe sein");
    }
  }

  private void assertUnique(PolitischeGruppe politischeGruppe) {
    if (dao.isEntityWithUKPresent(politischeGruppe.getPolitischeGruppeUK())) {
      throw new IllegalStateException("Eine Politische Gruppe mit <" + politischeGruppe.getPolitischeGruppeUK() + "> kann nicht angelegt werden, da eine solche politische Gruppe bereits existiert.");
    }
  }

  private Wahl attach(Wahl wahl) {
    return wahlDAO.attach(wahl);
  }
}
