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

import eu.dnetlib.validator2.validation.guideline.Builders;
import eu.dnetlib.validator2.validation.guideline.openaire.AbstractOpenAireProfile;
import eu.dnetlib.validator2.validation.utils.RegexValuePredicate;

import static eu.dnetlib.validator2.validation.utils.SupportedRegExs.COMPILED_DOI_REG_EX;
import static eu.dnetlib.validator2.validation.utils.SupportedRegExs.COMPILED_YYYY_MM_DD_REGEX;

public abstract class AbstractCrisProfile extends AbstractOpenAireProfile {

    private static final String[] OA_MANDATE_VOCABULARY = {"true", "false"};
    private static final String[] ACCESS_VOCABULARY     = {
            "http://purl.org/coar/access_right/c_abf2", "http://purl.org/coar/access_right/c_f1cf",
            "http://purl.org/coar/access_right/c_16ec", "http://purl.org/coar/access_right/c_14cb"
    };

    //Cross-referenced specs (WIP)
    static final Builders.ElementSpecBuilder PERSON_SPEC      = null;
    static final Builders.ElementSpecBuilder ORG_UNIT_SPEC    = null;
    static final Builders.ElementSpecBuilder PROJECT_SPEC     = null;
    static final Builders.ElementSpecBuilder FUNDING_SPEC     = null;
    static final Builders.ElementSpecBuilder EVENT_SPEC       = null;
    static final Builders.ElementSpecBuilder PATENT_SPEC      = null;
    static final Builders.ElementSpecBuilder PRODUCT_SPEC     = null;
    static final Builders.ElementSpecBuilder PUBLICATION_SPEC = null;
    static final Builders.ElementSpecBuilder EQUIPMENT_SPEC   = null;

    //Sub-specs with multiple Occurrences among different Cris Profiles
    static final Builders.ElementSpecBuilder ACRONYM_SPEC = Builders.
            forOptionalElement("Acronym");

    static final Builders.ElementSpecBuilder NAME_SPEC = Builders.
            forOptionalRepeatableElement("Name");

    static final Builders.ElementSpecBuilder IDENTIFIER_SPEC = Builders.
            forOptionalRepeatableElement("Identifier").
            withMandatoryAttribute("type");

    static final Builders.ElementSpecBuilder DESCRIPTION_SPEC = Builders.
            forOptionalRepeatableElement("Description");

    static final Builders.ElementSpecBuilder SUBJECT_SPEC = Builders.
            forOptionalRepeatableElement("Subject").
            withMandatoryAttribute("scheme");

    static final Builders.ElementSpecBuilder KEYWORD_SPEC = Builders.
            forOptionalRepeatableElement("Keyword");

    static final Builders.ElementSpecBuilder TITLE_SPEC = Builders.
            forOptionalRepeatableElement("Title");

    static final Builders.ElementSpecBuilder ABSTRACT_SPEC = Builders.
            forOptionalRepeatableElement("Abstract");

    static final Builders.ElementSpecBuilder START_DATE_SPEC = Builders.
            forOptionalElement("StartDate").
            allowedValues(new RegexValuePredicate(COMPILED_YYYY_MM_DD_REGEX)); //TODO: Add optional time zone indication in regex

    static final Builders.ElementSpecBuilder END_DATE_SPEC = Builders.
            forOptionalElement("EndDate").
            allowedValues(new RegexValuePredicate(COMPILED_YYYY_MM_DD_REGEX)); //TODO: Add optional time zone indication in regex

    static final Builders.ElementSpecBuilder OA_MANDATE_SPEC = Builders.
            forOptionalRepeatableElement("OAMandate").
            withMandatoryAttribute("mandated", OA_MANDATE_VOCABULARY).
            withOptionalAttribute("uri");

    static final Builders.ElementSpecBuilder ELECTRONIC_ADDRESS_SPEC = Builders.
            forOptionalRepeatableElement("ElectronicAddress");

    static final Builders.ElementSpecBuilder VERSION_INFO_SPEC = Builders.
            forOptionalRepeatableElement("VersionInfo");

    static final Builders.ElementSpecBuilder DOI_SPEC = Builders.
            forOptionalElement("DOI").
            allowedValues(new RegexValuePredicate(COMPILED_DOI_REG_EX));

    static final Builders.ElementSpecBuilder HANDLE_SPEC = Builders.
            forOptionalElement("Handle");

    static final Builders.ElementSpecBuilder URL_SPEC = Builders.
            forOptionalElement("URL");

    static final Builders.ElementSpecBuilder URN_SPEC = Builders.
            forOptionalElement("URN");

    static final Builders.ElementSpecBuilder LICENSE_SPEC = Builders.
            forOptionalRepeatableElement("License").
            withMandatoryAttribute("scheme");

    //TODO: Add namespace
    static final Builders.ElementSpecBuilder NS4_ACCESS_SPEC = Builders.
            forOptionalElement("Access").
            allowedValues(ACCESS_VOCABULARY);

    static final Builders.ElementSpecBuilder STATUS_SPEC = Builders.
            forOptionalRepeatableElement("Status").
            withMandatoryAttribute("scheme");

    public AbstractCrisProfile(String name) {
        super(name);
    }

}
