package mariaJava;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class InActionQuiz21 {
	public void inActionQuiz21() {
		System.out.println("Quiz 2.1");
		prettyPrintApple();
	}
	
	public void prettyPrintApple() {
		List<Apple> inventory = createInventoryOfApples();

		//Filter out some apples:
		System.out.println("Filter using streams and lambda");
		List<Apple> result = inventory.stream()
			.filter((Apple a) -> a.getWeight() > 150)
			.collect(Collectors.toList());
	
		System.out.println("No of heavy apples: " + result.size());
		
		System.out.println("Filter using Predicate test");
		Predicate<Apple> p1 = (Apple a) -> a.getWeight() > 150;
		Predicate<Apple> p2 = (Apple a) -> a.getColor().equals("green");
		//Print the weight all apples:
		filterStuff(inventory, p2);
		
		//Generic filter stuff:
		genericFilter(inventory, p2);

		//Testa olika sätt att göra en flexibel printer genom att göra olika implementationer:
		AppleFormatter formatter1 = new AppleSimpleFormatter();
		for(Apple a: inventory) {
			String output = formatter1.accept(a);
			System.out.println(output);
		}
		
		AppleFormatter formatter2 = new AppleFancyFormatter();
		for(Apple a: inventory) {
			String output = formatter2.accept(a);
			System.out.println(output);
		}
		//Abstrahera genom att passa in detta som ett argument:
		System.out.println("Passing multiple behavior:");
		prettyPrintApple(inventory, new AppleSimpleFormatter());
		prettyPrintApple(inventory, new AppleFancyFormatter());
		
	}
	
	
	public void prettyPrintApple(List<Apple> inventory, AppleFormatter formatter) {
		for(Apple a: inventory) {
			String output = formatter.accept(a);
			System.out.println(output);
		}
	}
	
	public interface AppleFormatter {
		String accept(Apple a);
	}
	public class AppleFancyFormatter implements AppleFormatter {

		@Override
		public String accept(Apple a) {
			String characteristic = a.getWeight() > 150? "heavy":"light";
			return "A " + characteristic + " " + a.getColor() + " apple";
		}
	}
	
	public class AppleSimpleFormatter implements AppleFormatter {

		@Override
		public String accept(Apple a) {
			return "An apple of " + a.getWeight() + "g";
		}
		
	}
	
	private List<Apple> filterStuff(List<Apple> inventory, Predicate<Apple> p) {
		List<Apple> result = new ArrayList<Apple>();
		
		for(Apple a: inventory) {
			if (p.test(a)) {
				result.add(a);
			}
		}
		System.out.println("No of apples due to predicate: " + result.size());
		
		return result;
	}	
	
	public <T> List<T> genericFilter(List<T> inventory, Predicate<T> predicate) {
		List<T> result = new ArrayList<T>();
		
		for(T e:inventory) {
			if(predicate.test(e)) {
				result.add(e);
			}
		}
		System.out.println("No of generic items, due to predicate: " + result.size());
		return result;
	}
	
	
	//----
	private List<Apple> createInventoryOfApples() {
		Apple a1 = new Apple(100, "red");
		Apple a2 = new Apple(140, "red");
		Apple a3 = new Apple(160,  "green");
		
		List<Apple> inventory = new ArrayList<Apple>();
		inventory.add(a1);
		inventory.add(a2);
		inventory.add(a3);
		
		return inventory;
	}

}
