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

import eu.dnetlib.validator2.validation.guideline.Builders;
import eu.dnetlib.validator2.validation.guideline.Cardinality;
import eu.dnetlib.validator2.validation.guideline.ElementSpec;
import eu.dnetlib.validator2.validation.guideline.Guideline;
import eu.dnetlib.validator2.validation.utils.RegexValuePredicate;
import org.w3c.dom.Document;

import java.util.Collection;

import static eu.dnetlib.validator2.validation.utils.SupportedRegExs.*;

public class CrisPersonV111Profile extends AbstractCrisProfile {

    private static final String[] GENDER_VOCABULARY = { "m", "f" };

    private static final Builders.ElementSpecBuilder PERSON_NAME_SPEC = Builders.
            forOptionalElement("PersonName").
            withSubElement(Builders.
                    forOptionalElement("FamilyNames")).
            withSubElement(Builders.
                    forOptionalElement("FirstNames")).
            withSubElement(Builders.
                    forOptionalElement("OtherNames"));

    private static final Builders.ElementSpecBuilder GENDER_SPEC = Builders.
            forOptionalElement("Gender").
            allowedValues(GENDER_VOCABULARY);

    private static final Builders.ElementSpecBuilder ORCID_SPEC = Builders.
            forOptionalElement("ORCID").
            allowedValues(new RegexValuePredicate(COMPILED_ORCID_REG_EX));

    private static final Builders.ElementSpecBuilder ALTERNATIVE_ORCID_SPEC = Builders.
            forOptionalRepeatableElement("AlternativeORCID").
            allowedValues(new RegexValuePredicate(COMPILED_ORCID_REG_EX));

    private static final Builders.ElementSpecBuilder RESEARCHER_ID_SPEC = Builders.
            forOptionalElement("ResearcherID").
            allowedValues(new RegexValuePredicate(COMPILED_RESEARCHER_ID_REG_EX));

    private static final Builders.ElementSpecBuilder ALTERNATIVE_RESEARCHER_ID_SPEC = Builders.
            forOptionalRepeatableElement("AlternativeResearcherID").
            allowedValues(new RegexValuePredicate(COMPILED_RESEARCHER_ID_REG_EX));

    private static final Builders.ElementSpecBuilder SCOPUS_AUTHOR_ID_SPEC = Builders.
            forOptionalElement("ScopusAuthorID").
            allowedValues(new RegexValuePredicate(COMPILED_SCOPUS_AUTHOR_ID_REG_EX));

    private static final Builders.ElementSpecBuilder ALTERNATIVE_SCOPUS_AUTHOR_ID_SPEC = Builders.
            forOptionalRepeatableElement("AlternativeScopusAuthorID").
            allowedValues(new RegexValuePredicate(COMPILED_SCOPUS_AUTHOR_ID_REG_EX));

    private static final Builders.ElementSpecBuilder ISNI_SPEC = Builders.
            forOptionalElement("ISNI").
            allowedValues(new RegexValuePredicate(COMPILED_ISNI_REG_EX));

    private static final Builders.ElementSpecBuilder ALTERNATIVE_ISNI_SPEC = Builders.
            forOptionalRepeatableElement("AlternativeISNI").
            allowedValues(new RegexValuePredicate(COMPILED_ISNI_REG_EX));

    private static final Builders.ElementSpecBuilder DAI_SPEC = Builders.
            forOptionalElement("DAI").
            allowedValues(new RegexValuePredicate(COMPILED_DAI_REG_EX));

    private static final Builders.ElementSpecBuilder ALTERNATIVE_DAI_SPEC = Builders.
            forOptionalRepeatableElement("AlternativeDAI").
            allowedValues(new RegexValuePredicate(COMPILED_DAI_REG_EX));

    private static final Builders.ElementSpecBuilder AFFILIATION_SPEC = Builders.
            forOptionalRepeatableElement("Affiliation").
            withSubElement(ORG_UNIT_SPEC); //TODO: Pass proper spec

    private static final ElementSpec PERSON_SPEC = Builders.
            forMandatoryElement("Person", Cardinality.ONE).
            withMandatoryAttribute("id").
            withSubElement(PERSON_NAME_SPEC).
            withSubElement(GENDER_SPEC).
            withSubElement(ORCID_SPEC).
            withSubElement(ALTERNATIVE_ORCID_SPEC).
            withSubElement(RESEARCHER_ID_SPEC).
            withSubElement(ALTERNATIVE_RESEARCHER_ID_SPEC).
            withSubElement(SCOPUS_AUTHOR_ID_SPEC).
            withSubElement(ALTERNATIVE_SCOPUS_AUTHOR_ID_SPEC).
            withSubElement(ISNI_SPEC).
            withSubElement(ALTERNATIVE_ISNI_SPEC).
            withSubElement(DAI_SPEC).
            withSubElement(ALTERNATIVE_DAI_SPEC).
            withSubElement(ELECTRONIC_ADDRESS_SPEC).
            withSubElement(AFFILIATION_SPEC).
            build();

    public CrisPersonV111Profile() {
        super("OpenAIRE Guidelines for Patent element of CRIS Managers v1.1.1");
    }

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

    @Override
    public Guideline<Document> guideline(String guidelineName) {
        return null;
    }

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