package de.ivu.elect.presentation.benutzerverwaltung.form;

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;

import de.ivu.elect.business.benutzerverwaltung.boundary.PermissionService;
import de.ivu.elect.business.benutzerverwaltung.boundary.RolleExtendedDAO;
import de.ivu.elect.business.benutzerverwaltung.entity.Rolle;
import de.ivu.elect.business.benutzerverwaltung.entity.RolleMeta;
import de.ivu.elect.business.benutzerverwaltung.entity.RollePickListProperty;
import de.ivu.elect.business.benutzerverwaltung.entity.RolleTyp;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.presentation.ViewFormBuilder;
import de.ivu.elect.presentation.benutzerverwaltung.PermissionServiceHelper;

/**
 *  on 08.02.2017.
 */
public abstract class AbstractEntityMitRollenViewFormBuilder extends ViewFormBuilder {

  private static final long serialVersionUID = 1L;

  private final Map<RolleTyp, RollePickListProperty> rollenPropertiesNachTyp = new EnumMap<>(RolleTyp.class);

  @Inject
  private transient PermissionServiceHelper permissionServiceHelper;

  @Inject
  protected transient RolleExtendedDAO rolleDao;

  @Inject
  private transient RolleMeta rolleMeta;


  protected void addRolleProperties(FormBuilder formBuilder, Set<Rolle> rolles, Mandant mandant) {
    rollenPropertiesNachTyp.clear();

    Map<RolleTyp, List<Rolle>> zugeordneteRollenNachTyp = new EnumMap<>(RolleTyp.class);
    Map<RolleTyp, List<Rolle>> verfuegbareRollenNachTyp = new EnumMap<>(RolleTyp.class);

    for (RolleTyp rolleTyp : RolleTyp.values()) {
      zugeordneteRollenNachTyp.put(rolleTyp, new ArrayList<>());
      verfuegbareRollenNachTyp.put(rolleTyp, new ArrayList<>());
    }

    for (Rolle rolle : getPossibleRolles()) {
      RolleTyp key = RolleTyp.valuePotentiell(rolle, rolleDao);
      if (key != null) {
        verfuegbareRollenNachTyp.get(key).add(rolle);
      }
    }

    for (Rolle rolle : rolles) {
      RolleTyp key = RolleTyp.valuePotentiell(rolle, rolleDao);
      if (key != null) {
        zugeordneteRollenNachTyp.get(key).add(rolle);
      }
    }

    boolean gruppenUebernehmen = isGruppenUebernehmen(mandant);
    for (RolleTyp rolleTyp : RolleTyp.values()) {
      if (!verfuegbareRollenNachTyp.get(rolleTyp).isEmpty()) {
        RollePickListProperty property = new RollePickListProperty(rolleMeta, verfuegbareRollenNachTyp.get(rolleTyp), zugeordneteRollenNachTyp.get(rolleTyp), rolleTyp);
        formBuilder.addProperty(property).withReadonly(gruppenUebernehmen); // Wenn der LoginService die Rollen liefert, dann keine Auswahl von Rollen anbieten => deaktivieren
        if (!gruppenUebernehmen) {
          rollenPropertiesNachTyp.put(rolleTyp, property);
        }
      }
    }
  }

  protected abstract boolean isGruppenUebernehmen(Mandant mandant);

  protected Set<Rolle> getPossibleRolles() {
    // ELECT-580
    return permissionServiceHelper.getAlleRollenDieVomPrincipalZugewiesenWerdenKoennen();
  }

  public Map<RolleTyp, RollePickListProperty> getRollenPropertiesNachTyp() {
    return rollenPropertiesNachTyp;
  }

}
