package be.iminds.ilabt.jfed.experimenter_gui.editor.rspec_validation;

import be.iminds.ilabt.jfed.rspec.model.ModelRspecType;
import be.iminds.ilabt.jfed.rspec.model.javafx_impl.FXModelRspec;
import be.iminds.ilabt.jfed.rspec.model.javafx_impl.FXRspecInterface;
import be.iminds.ilabt.jfed.rspec.rspec_source.RequestRspecSource;
import javafx.scene.control.Alert;
import javafx.stage.Window;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.stream.Collectors;

/**
 * User: twalcari
 * Date: 1/22/2015
 * Time: 16:44
 */
public class InterfaceIdsValidator implements RspecValidator {
    private static final Logger LOG = LoggerFactory.getLogger(InterfaceIdsValidator.class);

    @Override
    public RspecValidationResult validateRSpec(RspecCheckReason reason, RequestRspecSource requestRspecSource, Window dialogOwner) {
        FXModelRspec modelRspec = requestRspecSource.getModelRspec(ModelRspecType.FX);
        assert (modelRspec != null);

        List<String> invalidIds = modelRspec.getLinks().stream()
                .flatMap(link -> link.getInterfaces().stream())
                .filter(rspecIface -> !rspecIface.isBound())
                .map(FXRspecInterface::getClientId)
                .distinct().sorted()
                .collect(Collectors.toList());

        if (!invalidIds.isEmpty()) {

            List<String> unboundNodeIfaces = modelRspec.getNodes().stream()
                    .flatMap(node -> node.getInterfaces().stream())
                    .filter(rspecIface -> !rspecIface.isBound())
                    .map(FXRspecInterface::getClientId)
                    .distinct().sorted()
                    .collect(Collectors.toList());


            Alert errorAlert = new Alert(Alert.AlertType.ERROR);
            errorAlert.setHeaderText("Invalid interface references");
            errorAlert.setTitle("Invalid interface references");
            errorAlert.setContentText("The Rspec contains the following link interface reference ids in links that " +
                    "could not be matched to an interface on a node: "
                    + invalidIds.stream().collect(Collectors.joining(", ")) + ".\n\n"
                    + "The following node interfaces have nothing bound to it: "
                    + unboundNodeIfaces.stream().collect(Collectors.joining(", ")) + ".");

            errorAlert.showAndWait();

            //abort
            return new RspecValidationResult(requestRspecSource, true);
        } else {
            //everything is OK
            return null;
        }
    }
}
