package eu.dnetlib.validator2.validation.guideline.openaire;

import eu.dnetlib.validator2.validation.guideline.*;
import org.w3c.dom.Document;

import java.util.*;
import java.util.stream.Collectors;

import static eu.dnetlib.validator2.validation.guideline.Cardinality.ONE_TO_N;

public final class I2_01M extends AbstractOpenAireProfile {

    private static final ElementSpec I2_01M_SPEC_1 = Builders.
            forMandatoryElement("subject", ONE_TO_N).
            withOptionalAttribute("subjectScheme").
            withOptionalAttribute("schemeURI").
            build();

    private static final ElementSpec I2_01M_SPEC_2 = Builders.
//            forMandatoryElement("rights", ONE_TO_N).
//            withMandatoryAttribute("rightsURI").
//            build();
        forMandatoryIfApplicableElement("rights", ONE_TO_N, AbstractOpenAireProfile.elementIsPresent("rights")).
            atPosition(ElementPosition.FIRST).
            withMandatoryAttribute("rightsURI").
            build();


    //TODO: weights for guidelines haven't been finalized. They've been given an arbitrary value of 1.
    public static SyntheticGuideline I2_01M_1 = SyntheticGuideline.of("Subject", 5, I2_01M_SPEC_1);
    public static SyntheticGuideline I2_01M_2 = SyntheticGuideline.of("Rights", 5, I2_01M_SPEC_2);
    private static final List<Guideline<Document>> GUIDELINES = Collections.unmodifiableList(
            Arrays.asList(
                    I2_01M_1,
                    I2_01M_2
            )
    );

    private static final Map<String, Guideline> GUIDELINE_MAP = GUIDELINES.
            stream().
            collect(Collectors.toMap(Guideline::getName, (guideline) -> guideline));

    private static final int MAX_SCORE = GUIDELINES.stream().map(Guideline::getWeight).reduce(0, Integer::sum);

    public I2_01M() {
        super("Metadata uses FAIR-compliant vocabularies");
    }

    @Override
    public Collection<? extends Guideline<Document>> guidelines() {
        return GUIDELINES;
    }

    /**
     *
     * @param guidelineName
     * @return
     */
    @Override
    public Guideline guideline(String guidelineName) {
        return GUIDELINE_MAP.get(guidelineName);
    }

    @Override
    public int maxScore() { return MAX_SCORE; }
}