// Path: domain-model/src/main/java/net/safedata/java8/training/model/Product.java
// public class Product extends AbstractEntity {
// 
//     private final int id;
//     private final String name;
//     private final double price;
//     private final Discount discount;
//     private final List<String> tags;
// 
//     public Product(final int id, final String name, final double price, final Discount discount,
//                    final List<String> tags) {
//         this.id = id;
//         this.name = name;
//         this.price = price;
//         this.discount = discount;
//         this.tags = tags;
//     }
// 
//     public Product(final int id, final String name, final double price, final Discount discount) {
//         this.id = id;
//         this.name = name;
//         this.price = price;
//         this.discount = discount;
//         this.tags = null;
//     }
// 
//     public Product(final int id, final String name, final double price) {
//         this.id = id;
//         this.name = name;
//         this.price = price;
//         this.discount = null;
//         this.tags = null;
//     }
// 
//     public int getId() {
//         return id;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public double getPrice() {
//         return price;
//     }
// 
//     public Optional<Discount> getDiscount() {
//         return Optional.ofNullable(discount);
//     }
// 
//     public Optional<List<String>> getTags() {
//         return Optional.ofNullable(tags);
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (!(o instanceof Product)) return false;
//         Product product = (Product) o;
//         return id == product.id &&
//                 Objects.equals(name, product.name) &&
//                 Objects.equals(price, product.price);
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(id, name, price);
//     }
// 
//     @Override
//     public String toString() {
//         return id + ", " + name + ": " + price;
//     }
// }
// 
// Path: s01/s01e05-suppliers/src/main/java/net/safedata/java8/training/supplier/service/ProductService.java
// public class ProductService {
// 
//     private static final Random RANDOM = new Random();
// 
//     private static final NumberFormat NUMBER_FORMAT = new DecimalFormat("##.##");
// 
//     public Supplier<Product> generateRandomProduct() {
//         // advice - try not to do not do this at home (or in your projects)
//         // (this = mixing lambda expressions and try / catch statements)
//         return () -> {
//             try {
//                 return new Product(RANDOM.nextInt(500), "A fancy little random product",
//                                    Double.parseDouble(NUMBER_FORMAT.format(RANDOM.nextDouble() * 100)));
//             } catch (final NumberFormatException e) {
//                 throw new IllegalArgumentException("Invalid number");
//             }
//         };
//     }
// }


import net.safedata.java8.training.model.Product;
import net.safedata.java8.training.supplier.service.ProductService;
import java.util.Random;
import java.util.function.Supplier;
package net.safedata.java8.training.supplier;



/**
 * A few {@link java.util.function.Supplier} usage samples
 */
public class SuppliersMain {

    public static void main(String[] args) {
        simpleSuppliers();

        productSuppliers();

        sectionSuppliers();

        managerSuppliers();
    }

    private static void simpleSuppliers() {
        final Supplier<Double> doubleSupplier = () -> new Random(2525325).nextDouble();
        System.out.println(doubleSupplier.get());

        final Supplier<String> holidaySupplier = () -> "I want a holiday, not just a weekend :)";
        System.out.println(holidaySupplier.get());

        final Supplier<RuntimeException> runtimeExceptionSupplier = () ->
                                                new IllegalArgumentException("Nope");
        System.err.println(runtimeExceptionSupplier.get().getMessage());

        // TODO try other simple Suppliers - String, Boolean, ...
    }

    private static void productSuppliers() {
        final ProductService productService = new ProductService();

// Path: domain-model/src/main/java/net/safedata/java8/training/model/Product.java
// public class Product extends AbstractEntity {
// 
//     private final int id;
//     private final String name;
//     private final double price;
//     private final Discount discount;
//     private final List<String> tags;
// 
//     public Product(final int id, final String name, final double price, final Discount discount,
//                    final List<String> tags) {
//         this.id = id;
//         this.name = name;
//         this.price = price;
//         this.discount = discount;
//         this.tags = tags;
//     }
// 
//     public Product(final int id, final String name, final double price, final Discount discount) {
//         this.id = id;
//         this.name = name;
//         this.price = price;
//         this.discount = discount;
//         this.tags = null;
//     }
// 
//     public Product(final int id, final String name, final double price) {
//         this.id = id;
//         this.name = name;
//         this.price = price;
//         this.discount = null;
//         this.tags = null;
//     }
// 
//     public int getId() {
//         return id;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public double getPrice() {
//         return price;
//     }
// 
//     public Optional<Discount> getDiscount() {
//         return Optional.ofNullable(discount);
//     }
// 
//     public Optional<List<String>> getTags() {
//         return Optional.ofNullable(tags);
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (!(o instanceof Product)) return false;
//         Product product = (Product) o;
//         return id == product.id &&
//                 Objects.equals(name, product.name) &&
//                 Objects.equals(price, product.price);
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(id, name, price);
//     }
// 
//     @Override
//     public String toString() {
//         return id + ", " + name + ": " + price;
//     }
// }
// 
// Path: s01/s01e05-suppliers/src/main/java/net/safedata/java8/training/supplier/service/ProductService.java
// public class ProductService {
// 
//     private static final Random RANDOM = new Random();
// 
//     private static final NumberFormat NUMBER_FORMAT = new DecimalFormat("##.##");
// 
//     public Supplier<Product> generateRandomProduct() {
//         // advice - try not to do not do this at home (or in your projects)
//         // (this = mixing lambda expressions and try / catch statements)
//         return () -> {
//             try {
//                 return new Product(RANDOM.nextInt(500), "A fancy little random product",
//                                    Double.parseDouble(NUMBER_FORMAT.format(RANDOM.nextDouble() * 100)));
//             } catch (final NumberFormatException e) {
//                 throw new IllegalArgumentException("Invalid number");
//             }
//         };
//     }
// }


// Path: s01/s01e05-suppliers/src/main/java/net/safedata/java8/training/supplier/SuppliersMain.java
import net.safedata.java8.training.model.Product;
import net.safedata.java8.training.supplier.service.ProductService;
import java.util.Random;
import java.util.function.Supplier;

package net.safedata.java8.training.supplier;



/**
 * A few {@link java.util.function.Supplier} usage samples
 */
public class SuppliersMain {

    public static void main(String[] args) {
        simpleSuppliers();

        productSuppliers();

        sectionSuppliers();

        managerSuppliers();
    }

    private static void simpleSuppliers() {
        final Supplier<Double> doubleSupplier = () -> new Random(2525325).nextDouble();
        System.out.println(doubleSupplier.get());

        final Supplier<String> holidaySupplier = () -> "I want a holiday, not just a weekend :)";
        System.out.println(holidaySupplier.get());

        final Supplier<RuntimeException> runtimeExceptionSupplier = () ->
                                                new IllegalArgumentException("Nope");
        System.err.println(runtimeExceptionSupplier.get().getMessage());

        // TODO try other simple Suppliers - String, Boolean, ...
    }

    private static void productSuppliers() {
        final ProductService productService = new ProductService();

        final Product product = productService.generateRandomProduct().get();