// Path: warehouse-model/src/main/java/warehouse/BoxLabel.java
// @Value
// public class BoxLabel {
//     private final String refNo;
//     private final int quantity;
//     private final String boxType;
// }


import lombok.Value;
import warehouse.BoxLabel;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toMap;
package warehouse.products;




/**
 * Created by michal on 23.10.2017.
 */
public class CartValidator implements StorageUnitValidator {

    private final String refNo;
    private final Map<String, Integer> requiredPositions;

    public CartValidator(String refNo, List<String> requiredProducts) {
        this.refNo = refNo;
        this.requiredPositions = Collections.unmodifiableMap(
                IntStream.range(0, requiredProducts.size()).boxed()
                        .collect(toMap(requiredProducts::get, Function.identity()))
        );
    }

    @Override
    public ValidationResult validate(RegisterNew registerNew) {
        Stream<String> notExpected = scanned(registerNew)
                .filter(Scanned::isViolated)
                .map(Scanned::violation);

        Stream<String> notFound = notFound(registerNew)
                .map(this::notFoundMessage);

        return new ValidationResult(
                Stream.concat(notFound, notExpected)
                        .collect(Collectors.toSet())
        );
    }

    private Stream<String> notFound(RegisterNew registerNew) {
        Set<String> actual = scannedRefNos(registerNew).collect(Collectors.toSet());
        return expected().filter(expected -> !actual.contains(expected));
    }

    private Stream<String> scannedRefNos(RegisterNew registerNew) {
        return registerNew.getScannedBoxes().stream()
// Path: warehouse-model/src/main/java/warehouse/BoxLabel.java
// @Value
// public class BoxLabel {
//     private final String refNo;
//     private final int quantity;
//     private final String boxType;
// }


// Path: warehouse-model/src/main/java/warehouse/products/CartValidator.java
import lombok.Value;
import warehouse.BoxLabel;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toMap;

package warehouse.products;




/**
 * Created by michal on 23.10.2017.
 */
public class CartValidator implements StorageUnitValidator {

    private final String refNo;
    private final Map<String, Integer> requiredPositions;

    public CartValidator(String refNo, List<String> requiredProducts) {
        this.refNo = refNo;
        this.requiredPositions = Collections.unmodifiableMap(
                IntStream.range(0, requiredProducts.size()).boxed()
                        .collect(toMap(requiredProducts::get, Function.identity()))
        );
    }

    @Override
    public ValidationResult validate(RegisterNew registerNew) {
        Stream<String> notExpected = scanned(registerNew)
                .filter(Scanned::isViolated)
                .map(Scanned::violation);

        Stream<String> notFound = notFound(registerNew)
                .map(this::notFoundMessage);

        return new ValidationResult(
                Stream.concat(notFound, notExpected)
                        .collect(Collectors.toSet())
        );
    }

    private Stream<String> notFound(RegisterNew registerNew) {
        Set<String> actual = scannedRefNos(registerNew).collect(Collectors.toSet());
        return expected().filter(expected -> !actual.contains(expected));
    }

    private Stream<String> scannedRefNos(RegisterNew registerNew) {
        return registerNew.getScannedBoxes().stream()
                .map(BoxLabel::getRefNo);