
package de.ivu.elect.business.benutzerverwaltung.boundary;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import javax.ejb.Stateless;
import javax.inject.Inject;

import de.ivu.elect.business.benutzerverwaltung.entity.Benutzer;
import de.ivu.elect.business.benutzerverwaltung.entity.QBenutzer;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.security.UseCaseSecure;
import de.ivu.elect.business.security.control.ElectExtendedUseCasePermissionFilter;
import de.ivu.elect.jee.entity.QueryDsl;


import static de.ivu.elect.business.benutzerverwaltung.boundary.PermissionService.isNotwendigeRechteVorhanden;

@Stateless
@UseCaseSecure(UseCasePermission.BENUTZER_SEARCH)
public class BenutzerSearch extends AbstractBenutzerSearch {

  @Inject
  private transient ElectExtendedUseCasePermissionFilter extendedElectUseCasePermissionFilter;

  public BenutzerSearch() {
    super();
  }

  @Override
  protected List<Benutzer> querySearchResult(BenutzerSearchParameters searchParameters) {
    QBenutzer benutzer = QBenutzer.benutzer;

    QueryDsl queryDsl = dao.getQueryDsl().from(benutzer);
    queryDsl.eq(benutzer.mandant, searchParameters.getMandant());
    queryDsl.likeIfNotBlank(benutzer.vorname, searchParameters.getVorname());
    queryDsl.likeIfNotBlank(benutzer.familienname, searchParameters.getFamilienname());
    queryDsl.likeIfNotBlank(benutzer.benutzerkennung, searchParameters.getBenutzerkennung());

    if (Boolean.TRUE.equals(searchParameters.isNurGesperrte())) {
      queryDsl.eq(benutzer.gesperrt, Boolean.TRUE);
    }

    queryDsl.orderBy(benutzer.benutzerkennung.asc());

    List<Benutzer> result = queryDsl.list(benutzer);

    if (!searchParameters.getRollen().isEmpty()) {
      result = result.stream().filter(b -> b.getRolles().containsAll(searchParameters.getRollen())).collect(Collectors.toList());
    }

    return result.stream()
            .filter(benutzerEntity -> searchParameters.getVorhandeneRechte().contains(UseCasePermission.BENUTZER_SEARCH_ALL) /*ELECT-12577*/ ||
            benutzerHatNurRollenMitRechten(benutzerEntity,
                searchParameters.getVorhandeneRechte()))
            .collect(Collectors.toCollection(() -> new ArrayList<>()));
  }

  protected boolean benutzerHatNurRollenMitRechten(Benutzer benutzer, Collection<UseCasePermission> rechte) {
    return benutzer.getRolles().stream()
            .allMatch(rolle ->
                    isNotwendigeRechteVorhanden(rolle.getRecht(),
                            rechte,
                            extendedElectUseCasePermissionFilter,
                            benutzer.getMandant().getPk()));
  }
}
