package org.example;

import domain.Domain;

import java.util.Arrays;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PredicateExamples {

  public static void main(String[] args) {
    predicate();
    predicateAnd();
    predicateOr();
    predicateNegate();
    predicateChaining();
    biPredicate();
    biPredicateAsFunctionArgument();
  }

  private static void biPredicateAsFunctionArgument() {
    List<Domain> domainList = Arrays.asList(new Domain("google.com", 1), new Domain("i-am-spammer.com", 10),
        new Domain("mkyong.com", 0), new Domain("microsoft.com", 2));
    BiPredicate<String, Integer> biPredicate = (x, y) -> {
      return (x.equals("google.com") || y == 0);
    };
    System.out.println(domainList
        .stream()
        .filter(domain -> biPredicate.test(domain.getName(), domain.getScore()))
        .collect(Collectors.toList()));
  }

  private static void biPredicate() {
    BiPredicate<String, Integer> biPredicate = (x, y) -> x.length() == y;
    System.out.println(biPredicate.test("Bat", 3));
  }

  private static void predicateChaining() {
    Predicate<String> startsWithA = x -> x.startsWith("A");
    Predicate<String> startsWithB = x -> x.startsWith("B");
    System.out.println(startsWithA.or(startsWithB).test("Bat"));
  }

  private static void predicateNegate() {
    List<String> list = Arrays.asList("A", "AA", "AAA", "B", "BB", "BBB");
    Predicate<String> startsWith = x -> x.startsWith("A");
    System.out.println(list.stream().filter(startsWith.negate()).collect(Collectors.toList()));
  }

  private static void predicateOr() {
    List<String> list = Arrays.asList("A", "AA", "AAA", "B", "BB", "BBB");
    Predicate<String> startsWith = x -> x.startsWith("A");
    Predicate<String> length = x -> x.length() > 2;
    System.out.println(list.stream().filter(startsWith.or(length)).collect(Collectors.toList()));
  }

  private static void predicate() {
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    Predicate<Integer> noGreaterThan = x -> x > 5;
    System.out.println(">>" + list.stream().filter(noGreaterThan).sorted().collect(Collectors.toList()));
  }

  private static void predicateAnd() {
    List<Integer> list = Arrays.asList(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19);
    Predicate<Integer> greaterThan = x -> x > 10;
    Predicate<Integer> lessThan = x -> x < 18;
    System.out.println(list.stream().filter(greaterThan.and(lessThan)).collect(Collectors.toList()));
  }


}