package eu.dnetlib.validator2.engine;

import eu.dnetlib.validator2.engine.builtins.XMLCardinalityRule;
import eu.dnetlib.validator2.validation.XMLApplicationProfile;
import eu.dnetlib.validator2.validation.guideline.*;
import eu.dnetlib.validator2.validation.guideline.openaire.LiteratureGuidelinesV3Profile;
import eu.dnetlib.validator2.validation.guideline.openaire.LiteratureGuidelinesV4Profile;
import eu.dnetlib.validator2.validation.task.ValidationTask;
import eu.dnetlib.validator2.validation.task.ValidationTaskOutput;
import org.w3c.dom.Document;

import java.util.Collection;
import java.util.concurrent.Executors;

public class Example {

    public static void createAndEvaluateRule(Document xmlDoc) {
        XMLCardinalityRule rule = XMLCardinalityRule.
                builder().
                setId("Test rule").
                setXPathExpression("//*[name()='something']").
                setRange(0, 5).
                setIsInclusive(true).
                build();

        RuleEngine.applyAndReport(rule, xmlDoc, new Reporter<>(Helper.Diagnostics.systemOut()));
    }

    public static void validateEstablishedGuideline(Document xmlDoc) {
        Guideline.Result result = LiteratureGuidelinesV4Profile.TITLE.validate(xmlDoc);

        XMLApplicationProfile profile2 = new LiteratureGuidelinesV3Profile();
        result = profile2.guideline("Title").validate(xmlDoc);
    }

    public static void createAndValidateCustomGuideline(Document xmlDoc) {
        SyntheticGuideline guideline = SyntheticGuideline.of("Test guideline", 1, Builders.
                forMandatoryElement("dc:title", Cardinality.ONE_TO_N).
                withOptionalAttribute("xml:lang").
                withOptionalAttribute("titleType",
                        "AlternativeTitle", "Subtitle", "TranslatedTitle", "Other").
                build()
        );

        Guideline.Result result = guideline.validate(xmlDoc);
    }

    public static void createAndValidateCustomRulesAsGuideline(Document xmlDoc, Collection<Rule<Document>> rules) {
        Guideline<Document> guideline = new AbstractGuideline<Document>("Whatever", 1) {
            @Override
            public Result validate(String id, Document document) {
                boolean result = Predicates.all(rules).test(document);
                return result ? StandardResult.forSuccess(1, null) : StandardResult.forFailure(null, null);
            }
        };
    }

    public static void createCustomValidationTask(Document xmlDoc, Collection<Rule<Document>> rules) {
        ValidationTask<Document, Rule<Document>> task = ValidationTask.Factory.newTask(Executors.newCachedThreadPool(), rules, xmlDoc);
        task.run((ValidationTaskOutput output) -> {});
    }

}
