// This program has been developed by students from the bachelor Computer Science at Utrecht
// University within the Software Project course.
// © Copyright Utrecht University (Department of Information and Computing Sciences)
export type PriorityFilterPredicate<T> = {
  priority: number;
  predicate: (element: T) => boolean | null; // The predicate and its priority are ignored if it returns null.
}

/**
 * Applies a list of priority predicates to an element. For all predicates that don't return null, if the ones with the highest level return true, then this function returns true. Or conversely, if the one with the highest level returns false, then this function returns false.
 * @param element The element to apply the predicates to.
 * @param predicates The list of predicates to apply.
 */
export function applyPriorityPredicates<T>(element: T, predicates: PriorityFilterPredicate<T>[]): boolean {
  let highestPriority = -1;
  let highestKeep = true;
  for (const predicate of predicates) {
    if (predicate.priority >= highestPriority) {
      const predicateKeep = predicate.predicate(element);
      if (predicateKeep === null) continue; // This predicate doesn't care about the element, so skip it
      if (predicate.priority > highestPriority) highestKeep = true;
      highestPriority = predicate.priority;
      highestKeep = highestKeep && predicateKeep;
    }
  }
  return highestKeep;
}
