
package de.ivu.elect.presentation.security;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import de.ivu.elect.business.gebietsbaum.entity.EntityMitGebiet;
import de.ivu.elect.business.gebietsbaum.entity.EntityMitGebieten;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;

public abstract class AbstractGebietSecurityFilter<T> implements Serializable {

  private static final long serialVersionUID = 1L;

  private final AbstractGebietSecurity gebietSecurity;

  protected AbstractGebietSecurityFilter(AbstractGebietSecurity gebietSecurity) {
    this.gebietSecurity = gebietSecurity;
  }

  protected AbstractGebietSecurity getGebietSecurity() {
    return gebietSecurity;
  }

  public static <T> AbstractGebietSecurityFilter<T> createKeinFilter() {
    return new AbstractGebietSecurityFilter<T>(null) {

      private static final long serialVersionUID = 1L;

      @Override
      public boolean isRechtVorhanden(T o) {
        return true;
      }

      @Override
      public List<T> filter(List<T> list) {
        return list;
      }
    };
  }

  public abstract boolean isRechtVorhanden(T o);

  public List<T> filter(List<T> list) {
    return list.stream().filter(this::isRechtVorhanden).collect(Collectors.toCollection(() -> new ArrayList<>(list.size())));
  }

  public static <E extends Gebiet> AbstractGebietSecurityFilter<E> createGebietSecurityFilter(AbstractGebietSecurity gebietSecurity) {
    return new AbstractGebietSecurityFilter<E>(gebietSecurity) {

      private static final long serialVersionUID = 1L;

      @Override
      public boolean isRechtVorhanden(E e) {
        return getGebietSecurity().isRechtVorhanden(e);
      }

      @Override
      public List<E> filter(List<E> list) {
        return getGebietSecurity().filterGebiete(list);
      }
    };
  }

  public static <E extends EntityMitGebiet> AbstractGebietSecurityFilter<E> createEntityMitGebietSecurityFilter(
      AbstractGebietSecurity gebietSecurity) {
    return new AbstractGebietSecurityFilter<E>(gebietSecurity) {

      private static final long serialVersionUID = 1L;

      @Override
      public boolean isRechtVorhanden(E e) {
        return getGebietSecurity().isRechtVorhanden(e);
      }

      @Override
      public List<E> filter(List<E> list) {
        return getGebietSecurity().filterEntityMitGebiet(list);
      }
    };
  }

  public static <E extends EntityMitGebieten> AbstractGebietSecurityFilter<E> createEntityMitGebietenSecurityFilter(
      AbstractGebietSecurity gebietSecurity) {
    return new AbstractGebietSecurityFilter<E>(gebietSecurity) {

      private static final long serialVersionUID = 1L;

      @Override
      public boolean isRechtVorhanden(E e) {
        return getGebietSecurity().isRechtVorhanden(e);
      }

      @Override
      public List<E> filter(List<E> list) {
        return getGebietSecurity().filterEntitiesMitGebieten(list);
      }
    };
  }
}
