from mhd_model.model.definitions import MHD_MODEL_V0_1_DEFAULT_SCHEMA_NAME
from mhd_model.model.v0_1.dataset.validation.profile.base import (
    EmbeddedRefValidation,
    RelationshipValidation,
)
from mhd_model.model.v0_1.dataset.validation.profile.definition import (
    CvNodeValidation,
    CvTermValidation,
    FilterCondition,
    MhDatasetValidation,
    NodePropertyValidation,
    NodeValidation,
    PropertyConstraint,
)
from mhd_model.model.v0_1.rules.managed_cv_terms import (
    COMMON_ASSAY_TYPES,
    COMMON_CHARACTERISTIC_DEFINITIONS,
    COMMON_MEASUREMENT_TYPES,
    COMMON_OMICS_TYPES,
    COMMON_PARAMETER_DEFINITIONS,
    COMMON_PROTOCOL_PARAMETERS,
    COMMON_PROTOCOLS,
    COMMON_TECHNOLOGY_TYPES,
)
from mhd_model.shared.model import CvTerm
from mhd_model.shared.validation.definitions import (
    AllowAnyCvTerm,
    AllowedChildrenCvTerms,
    AllowedCvList,
    AllowedCvTerms,
    CvTermPlaceholder,
    ParentCvTerm,
)

MHD_BASE_VALIDATION_V0_1 = MhDatasetValidation(
    schema=MHD_MODEL_V0_1_DEFAULT_SCHEMA_NAME
)

MHD_BASE_VALIDATION_V0_1.mhd_nodes = [
    NodeValidation(
        node_type="assay",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="assay",
                node_property_name="repository_identifier",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
            NodePropertyValidation(
                node_type="assay",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
            EmbeddedRefValidation(
                node_type="assay",
                node_property_name="metadata_file_ref",
                required=False,
                target_ref_types=["metadata-file"],
            ),
            EmbeddedRefValidation(
                node_type="assay",
                node_property_name="technology_type_ref",
                required=False,
                target_ref_types=["descriptor"],
            ),
            EmbeddedRefValidation(
                node_type="assay",
                node_property_name="assay_type_ref",
                required=False,
                target_ref_types=["descriptor"],
            ),
            EmbeddedRefValidation(
                node_type="assay",
                node_property_name="measurement_type_ref",
                required=False,
                target_ref_types=["descriptor"],
            ),
            EmbeddedRefValidation(
                node_type="assay",
                node_property_name="omics_type_ref",
                required=False,
                target_ref_types=["descriptor"],
            ),
            EmbeddedRefValidation(
                node_type="assay",
                node_property_name="protocol_refs",
                required=False,
                target_ref_types=["protocol"],
            ),
            EmbeddedRefValidation(
                node_type="assay",
                node_property_name="sample_run_refs",
                required=False,
                target_ref_types=["sample-run"],
            ),
        ],
        relationships=[
            RelationshipValidation(
                description="A link to a descriptor that describes the assay.",
                source="assay",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
                max_for_each_source=0,
            ),
            RelationshipValidation(
                description="A link to a study that the assay was conducted as part of it "
                "to generate data addressing study objectives",
                source="assay",
                relationship_name="part-of",
                reverse_relationship_name="has-assay",
                target="study",
                min=0,
                min_for_each_source=0,
                max_for_each_source=0,
            ),
            RelationshipValidation(
                description="A link to a protocol conducted in assay.",
                source="assay",
                relationship_name="follows",
                reverse_relationship_name="used-in",
                target="protocol",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="characteristic-definition",
        min=0,
        validations=[
            EmbeddedRefValidation(
                node_type="characteristic-definition",
                node_property_name="characteristic_type_ref",
                required=True,
                target_ref_types=["characteristic-type"],
            ),
            NodePropertyValidation(
                node_type="characteristic-definition",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="characteristic-definition",
                relationship_name="has-instance",
                reverse_relationship_name="instance-of",
                target="characteristic-value",
                min=2,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="characteristic-definition",
                relationship_name="has-type",
                reverse_relationship_name="type-of",
                target="characteristic-type",
                min=0,
                min_for_each_source=1,
                max_for_each_source=1,
            ),
            RelationshipValidation(
                source="characteristic-definition",
                relationship_name="used-in",
                reverse_relationship_name="has-characteristic-definition",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="derived-data-file",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="derived-data-file",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
            NodePropertyValidation(
                node_type="derived-data-file",
                node_property_name="format_ref",
                contraints=PropertyConstraint(required=True),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="derived-data-file",
                relationship_name="referenced-in",
                reverse_relationship_name="references",
                target="metadata-file",
                min=0,
                min_for_each_source=0,
                max_for_each_source=0,
            ),
            RelationshipValidation(
                source="derived-data-file",
                relationship_name="created-in",
                reverse_relationship_name="has-derived-data-file",
                target="study",
                min=0,
                min_for_each_source=1,
                max_for_each_source=1,
            ),
            RelationshipValidation(
                description="A link to a descriptor that describes the derived data file.",
                source="derived-data-file",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
                max_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="factor-definition",
        min=0,
        validations=[
            EmbeddedRefValidation(
                node_type="factor-definition",
                node_property_name="factor_type_ref",
                required=True,
                target_ref_types=["factor-type"],
            ),
            NodePropertyValidation(
                node_type="factor-definition",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="factor-definition",
                relationship_name="has-type",
                reverse_relationship_name="type-of",
                target="factor-type",
                min=0,
                min_for_each_source=0,
                max_for_each_source=0,
            ),
            RelationshipValidation(
                source="factor-definition",
                relationship_name="has-instance",
                reverse_relationship_name="instance-of",
                target="factor-value",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="factor-definition",
                relationship_name="used-in",
                reverse_relationship_name="has-factor-definition",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="metadata-file",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="metadata-file",
                node_property_name="url_list",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
            NodePropertyValidation(
                node_type="metadata-file",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
            NodePropertyValidation(
                node_type="metadata-file",
                node_property_name="format_ref",
                contraints=PropertyConstraint(required=True),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="metadata-file",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="metadata-file",
                relationship_name="referenced-in",
                reverse_relationship_name="references",
                target="metadata-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="metadata-file",
                relationship_name="describes",
                reverse_relationship_name="has-metadata-file",
                target="study",
                min=0,
                min_for_each_source=1,
                max_for_each_source=1,
            ),
            RelationshipValidation(
                source="metadata-file",
                relationship_name="references",
                reverse_relationship_name="referenced-in",
                target="derived-data-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="metadata-file",
                relationship_name="references",
                reverse_relationship_name="referenced-in",
                target="raw-data-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="metadata-file",
                relationship_name="references",
                reverse_relationship_name="referenced-in",
                target="result-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="metadata-file",
                relationship_name="references",
                reverse_relationship_name="referenced-in",
                target="supplementary-file",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="metabolite",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="metabolite",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="metabolite",
                relationship_name="identified-as",
                reverse_relationship_name="reported-identifier-of",
                target="metabolite-identifier",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="metabolite",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="metabolite",
                relationship_name="reported-in",
                reverse_relationship_name="reports",
                target="study",
                min=0,
                min_for_each_source=1,
            ),
        ],
    ),
    NodeValidation(
        node_type="organization",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="organization",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=10),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="organization",
                relationship_name="funds",
                reverse_relationship_name="funded-by",
                target="project",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="organization",
                relationship_name="funds",
                reverse_relationship_name="funded-by",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="organization",
                relationship_name="manages",
                reverse_relationship_name="managed-by",
                target="project",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="organization",
                relationship_name="coordinates",
                reverse_relationship_name="coordinated-by",
                target="project",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="organization",
                relationship_name="affiliates",
                reverse_relationship_name="affiliated-with",
                target="person",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="organization",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="parameter-definition",
        min=0,
        validations=[
            EmbeddedRefValidation(
                node_type="parameter-definition",
                node_property_name="parameter_type_ref",
                required=True,
                target_ref_types=["parameter-type"],
            ),
            NodePropertyValidation(
                node_type="parameter-definition",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="parameter-definition",
                relationship_name="has-instance",
                reverse_relationship_name="instance-of",
                target="parameter-value",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="parameter-definition",
                relationship_name="has-type",
                reverse_relationship_name="type-of",
                target="parameter-type",
                min=0,
                min_for_each_source=1,
                max_for_each_source=1,
            ),
            RelationshipValidation(
                source="parameter-definition",
                relationship_name="used-in",
                reverse_relationship_name="has-parameter-definition",
                target="protocol",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="person",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="person",
                node_property_name="full_name",
                contraints=PropertyConstraint(required=True, min_length=5),
            ),
            NodePropertyValidation(
                node_type="person",
                node_property_name="emails",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="person",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="person",
                relationship_name="affiliated-with",
                reverse_relationship_name="affiliates",
                target="organization",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="person",
                relationship_name="contributes",
                reverse_relationship_name="has-contributor",
                target="project",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="person",
                relationship_name="contributes",
                reverse_relationship_name="has-contributor",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="person",
                relationship_name="principal-investigator-of",
                reverse_relationship_name="has-principal-investigator",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="person",
                relationship_name="submits",
                reverse_relationship_name="submitted-by",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="person",
                relationship_name="author-of",
                reverse_relationship_name="has-author",
                target="publication",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="project",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="project",
                node_property_name="title",
                contraints=PropertyConstraint(required=True, min_length=25),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="project",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="project",
                relationship_name="funded-by",
                reverse_relationship_name="funds",
                target="organization",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="project",
                relationship_name="managed-by",
                reverse_relationship_name="manages",
                target="organization",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="project",
                relationship_name="coordinated-by",
                reverse_relationship_name="coordinates",
                target="organization",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="project",
                relationship_name="has-contributor",
                reverse_relationship_name="contributes",
                target="person",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="project",
                relationship_name="has-publication",
                reverse_relationship_name="describes",
                target="publication",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="project",
                relationship_name="has-study",
                reverse_relationship_name="part-of",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="protocol",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="protocol",
                node_property_name="name",
                contraints=PropertyConstraint(required=True),
            ),
            EmbeddedRefValidation(
                node_type="protocol",
                node_property_name="protocol_type_ref",
                required=True,
                target_ref_types=["protocol-type"],
            ),
            NodePropertyValidation(
                node_type="protocol",
                node_property_name="description",
                contraints=PropertyConstraint(required=False),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="protocol",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="protocol",
                relationship_name="used-in",
                reverse_relationship_name="follows",
                target="assay",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="protocol",
                relationship_name="has-parameter-definition",
                reverse_relationship_name="used-in",
                target="parameter-definition",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="protocol",
                relationship_name="used-in",
                reverse_relationship_name="has-protocol",
                target="study",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="protocol",
                relationship_name="has-type",
                reverse_relationship_name="type-of",
                target="protocol-type",
                min=0,
                min_for_each_source=1,
                max_for_each_source=1,
            ),
        ],
    ),
    NodeValidation(
        node_type="publication",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="publication",
                node_property_name="title",
                contraints=PropertyConstraint(required=True),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="publication",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="publication",
                relationship_name="describes",
                reverse_relationship_name="has-publication",
                target="project",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="publication",
                relationship_name="describes",
                reverse_relationship_name="has-publication",
                target="study",
                min=0,
                min_for_each_source=0,
                max_for_each_source=1,
            ),
            RelationshipValidation(
                source="publication",
                relationship_name="has-author",
                reverse_relationship_name="author-of",
                target="person",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="raw-data-file",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="raw-data-file",
                node_property_name="url_list",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
            NodePropertyValidation(
                node_type="raw-data-file",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="raw-data-file",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="raw-data-file",
                relationship_name="created-in",
                reverse_relationship_name="has-raw-data-file",
                target="study",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="raw-data-file",
                relationship_name="referenced-in",
                reverse_relationship_name="references",
                target="metadata-file",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="result-file",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="result-file",
                node_property_name="url_list",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
            NodePropertyValidation(
                node_type="result-file",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="result-file",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="result-file",
                relationship_name="created-in",
                reverse_relationship_name="has-result-file",
                target="study",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="result-file",
                relationship_name="referenced-in",
                reverse_relationship_name="references",
                target="metadata-file",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="sample",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="sample",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
            NodePropertyValidation(
                node_type="sample",
                node_property_name="repository_identifier",
                contraints=PropertyConstraint(required=True),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="sample",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="sample",
                relationship_name="has-factor-value",
                reverse_relationship_name="value-of",
                target="factor-value",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="sample",
                relationship_name="used-in",
                reverse_relationship_name="has-sample",
                target="study",
                min=0,
                min_for_each_source=1,
                max_for_each_source=1,
            ),
            RelationshipValidation(
                source="sample",
                relationship_name="derived-from",
                reverse_relationship_name="source-of",
                target="subject",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="sample",
                relationship_name="derived-from",
                reverse_relationship_name="source-of",
                target="specimen",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="sample",
                relationship_name="has-characteristic-value",
                reverse_relationship_name="value-of",
                target="characteristic-value",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="sample-run",
        min=0,
        validations=[
            EmbeddedRefValidation(
                node_type="sample-run",
                node_property_name="sample_ref",
                required=True,
                target_ref_types=["sample"],
            ),
            EmbeddedRefValidation(
                node_type="sample-run",
                node_property_name="raw_data_file_refs",
                required=True,
                target_ref_types=["raw-data-file"],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="sample-run",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="sample-run-configuration",
        min=0,
        validations=[
            EmbeddedRefValidation(
                node_type="sample-run-configuration",
                node_property_name="protocol_ref",
                required=True,
                target_ref_types=["protocol"],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="sample-run-configuration",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="study",
        min=1,
        validations=[
            EmbeddedRefValidation(
                node_type="study",
                node_property_name="created_by_ref",
                required=False,
                target_ref_types=["data-provider"],
            ),
            NodePropertyValidation(
                node_type="study",
                node_property_name="mhd_identifier",
                contraints=PropertyConstraint(required=True, min_length=8),
            ),
            NodePropertyValidation(
                node_type="study",
                node_property_name="repository_identifier",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
            EmbeddedRefValidation(
                node_type="study",
                node_property_name="protocol_refs",
                required=False,
                target_ref_types=["protocol"],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="study",
                relationship_name="provided-by",
                reverse_relationship_name="provides",
                target="data-provider",
                min=0,
                min_for_each_source=1,
                max_for_each_source=1,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-assay",
                reverse_relationship_name="part-of",
                target="assay",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="funded-by",
                reverse_relationship_name="funds",
                target="organization",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-characteristic-definition",
                reverse_relationship_name="used-in",
                target="characteristic-definition",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-derived-data-file",
                reverse_relationship_name="created-in",
                target="derived-data-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-factor-definition",
                reverse_relationship_name="used-in",
                target="factor-definition",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-repository-keyword",
                reverse_relationship_name="keyword-of",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-submitter-keyword",
                reverse_relationship_name="keyword-of",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="reports",
                reverse_relationship_name="reported-in",
                target="metabolite",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-metadata-file",
                reverse_relationship_name="describes",
                target="metadata-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-contributor",
                reverse_relationship_name="contributes",
                target="person",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-principal-investigator",
                reverse_relationship_name="principal-investigator-of",
                target="person",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="submitted-by",
                reverse_relationship_name="submits",
                target="person",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="part-of",
                reverse_relationship_name="has-study",
                target="project",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-protocol",
                reverse_relationship_name="used-in",
                target="protocol",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-publication",
                reverse_relationship_name="describes",
                target="publication",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-raw-data-file",
                reverse_relationship_name="created-in",
                target="raw-data-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-result-file",
                reverse_relationship_name="created-in",
                target="result-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-sample",
                reverse_relationship_name="used-in",
                target="sample",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="study",
                relationship_name="has-supplementary-file",
                reverse_relationship_name="created-in",
                target="supplementary-file",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="specimen",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="specimen",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
            NodePropertyValidation(
                node_type="specimen",
                node_property_name="repository_identifier",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="specimen",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="specimen",
                relationship_name="has-characteristic-value",
                reverse_relationship_name="value-of",
                target="characteristic-value",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="specimen",
                relationship_name="source-of",
                reverse_relationship_name="derived-from",
                target="sample",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="specimen",
                relationship_name="derived-from",
                reverse_relationship_name="source-of",
                target="subject",
                min=0,
                min_for_each_source=1,
            ),
        ],
    ),
    NodeValidation(
        node_type="subject",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="subject",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
            NodePropertyValidation(
                node_type="subject",
                node_property_name="repository_identifier",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="subject",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="subject",
                relationship_name="has-characteristic-value",
                reverse_relationship_name="value-of",
                target="characteristic-value",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="subject",
                relationship_name="source-of",
                reverse_relationship_name="derived-from",
                target="sample",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="subject",
                relationship_name="has-factor-value",
                reverse_relationship_name="value-of",
                target="factor-value",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="subject",
                relationship_name="source-of",
                reverse_relationship_name="derived-from",
                target="specimen",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    NodeValidation(
        node_type="supplementary-file",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="supplementary-file",
                node_property_name="url_list",
                contraints=PropertyConstraint(required=True, min_length=1),
            ),
            NodePropertyValidation(
                node_type="supplementary-file",
                node_property_name="name",
                contraints=PropertyConstraint(required=True, min_length=2),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="supplementary-file",
                relationship_name="described-as",
                reverse_relationship_name="describes",
                target="descriptor",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="supplementary-file",
                relationship_name="created-in",
                reverse_relationship_name="has-supplementary-file",
                target="study",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="supplementary-file",
                relationship_name="referenced-in",
                reverse_relationship_name="references",
                target="metadata-file",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
]

MHD_BASE_VALIDATION_V0_1.cv_nodes = [
    CvNodeValidation(
        node_type="characteristic-type",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="characteristic-type",
                node_property_name="name",
                contraints=PropertyConstraint(required=True),
            ),
            CvTermValidation(
                node_type="characteristic-type",
                validation=AllowedCvTerms(
                    cv_terms=list(COMMON_CHARACTERISTIC_DEFINITIONS.values())
                ),
                condition=[
                    FilterCondition(
                        name="Characteristic Type",
                        relationship_name="[embedded].characteristic_type_ref",
                        start_node_type="characteristic-definition",
                        expression="characteristic_type_ref",
                    )
                ],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="characteristic-type",
                relationship_name="type-of",
                reverse_relationship_name="has-type",
                target="characteristic-definition",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    CvNodeValidation(
        node_type="characteristic-value",
        has_value=True,
        min=0,
        validations=[
            CvTermValidation(
                node_type="characteristic-value",
                validation=AllowAnyCvTerm(
                    allowed_placeholder_values=[CvTermPlaceholder()],
                    allowed_other_sources=["wikidata", "ILX"],
                ),
            )
        ],
        relationships=[
            RelationshipValidation(
                source="characteristic-value",
                relationship_name="instance-of",
                reverse_relationship_name="has-instance",
                target="characteristic-definition",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="characteristic-value",
                relationship_name="value-of",
                reverse_relationship_name="has-characteristic-value",
                target="subject",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="characteristic-value",
                relationship_name="value-of",
                reverse_relationship_name="has-characteristic-value",
                target="specimen",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="characteristic-value",
                relationship_name="value-of",
                reverse_relationship_name="has-characteristic-value",
                target="sample",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    CvNodeValidation(
        node_type="data-provider",
        has_value=True,
        value_required=True,
        min=1,
        validations=[
            NodePropertyValidation(
                node_type="data-provider",
                node_property_name="value",
                contraints=PropertyConstraint(required=True, allowed_types="str"),
            ),
            CvTermValidation(
                node_type="data-provider",
                validation=AllowAnyCvTerm(allowed_other_sources=["wikidata", "ILX"]),
            ),
            CvTermValidation(
                node_type="data-provider",
                validation=AllowAnyCvTerm(allowed_other_sources=["wikidata", "ILX"]),
                condition=[
                    FilterCondition(
                        name="Data Provider",
                        relationship_name="[embedded].created_by_ref",
                        start_node_type=None,
                        expression="created_by_ref",
                    )
                ],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="data-provider",
                relationship_name="provides",
                reverse_relationship_name="provided-by",
                target="study",
                min=0,
                min_for_each_source=1,
                max_for_each_source=1,
            ),
        ],
    ),
    CvNodeValidation(
        node_type="descriptor",
        min=0,
        validations=[
            CvTermValidation(
                node_type="descriptor",
                validation=AllowedChildrenCvTerms(
                    parent_cv_terms=[
                        ParentCvTerm(
                            cv_term=CvTerm(
                                source="EDAM",
                                accession="EDAM:1915",
                                name="Format",
                            ),
                            index_cv_terms=False,
                        )
                    ]
                ),
                condition=[
                    FilterCondition(
                        name="File Format",
                        relationship_name="[embedded].format_ref",
                        start_node_type=None,
                        expression="format_ref",
                    )
                ],
            ),
            CvTermValidation(
                node_type="descriptor",
                validation=AllowedChildrenCvTerms(
                    parent_cv_terms=[
                        ParentCvTerm(
                            cv_term=CvTerm(
                                source="EDAM",
                                accession="EDAM:1915",
                                name="Format",
                            ),
                            index_cv_terms=False,
                        )
                    ]
                ),
                condition=[
                    FilterCondition(
                        name="File Format",
                        relationship_name="[embedded].compression_format_refs",
                        start_node_type=None,
                        expression="compression_format_refs",
                    )
                ],
            ),
            CvTermValidation(
                node_type="descriptor",
                validation=AllowedCvTerms(cv_terms=list(COMMON_ASSAY_TYPES.values())),
                condition=[
                    FilterCondition(
                        name="Analysis Type",
                        relationship_name="[embedded].assay_type_ref",
                        start_node_type="assay",
                        expression="assay_type_ref",
                    )
                ],
            ),
            CvTermValidation(
                node_type="descriptor",
                validation=AllowedCvTerms(
                    cv_terms=list(COMMON_MEASUREMENT_TYPES.values())
                ),
                condition=[
                    FilterCondition(
                        name="Measurement Type",
                        relationship_name="[embedded].measurement_type_ref",
                        start_node_type="assay",
                        expression="measurement_type_ref",
                    )
                ],
            ),
            CvTermValidation(
                node_type="descriptor",
                validation=AllowedCvTerms(
                    cv_terms=list(COMMON_TECHNOLOGY_TYPES.values())
                ),
                condition=[
                    FilterCondition(
                        name="Technology Type",
                        relationship_name="[embedded].technology_type_ref",
                        start_node_type="assay",
                        expression="technology_type_ref",
                    )
                ],
            ),
            CvTermValidation(
                node_type="descriptor",
                validation=AllowedCvTerms(cv_terms=list(COMMON_OMICS_TYPES.values())),
                condition=[
                    FilterCondition(
                        name="Omics Type",
                        relationship_name="[embedded].omics_type_ref",
                        start_node_type="assay",
                        expression="omics_type_ref",
                    )
                ],
            ),
            CvTermValidation(
                node_type="descriptor",
                validation=AllowAnyCvTerm(
                    allowed_other_sources=["wikidata", "ILX"],
                    allowed_placeholder_values=[CvTermPlaceholder()],
                ),
                condition=[
                    FilterCondition(
                        name="Keyword",
                        relationship_name="has-submitter-keyword",
                        start_node_type="study",
                    )
                ],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="assay",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="metadata-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="raw-data-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="derived-data-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="supplementary-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="result-file",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="metabolite",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="organization",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="person",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="project",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="publication",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="protocol",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="sample",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="subject",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="sample-run",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="sample-run-configuration",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="describes",
                reverse_relationship_name="described-as",
                target="metabolite",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="keyword-of",
                reverse_relationship_name="has-submitter-keyword",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="keyword-of",
                reverse_relationship_name="has-repository-keyword",
                target="study",
                min=0,
                min_for_each_source=0,
            ),
            RelationshipValidation(
                source="descriptor",
                relationship_name="keyword-of",
                reverse_relationship_name="has-repository-keyword",
                target="specimen",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    CvNodeValidation(
        node_type="factor-type",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="factor-type",
                node_property_name="name",
                contraints=PropertyConstraint(required=True),
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="factor-type",
                relationship_name="type-of",
                reverse_relationship_name="has-type",
                target="factor-definition",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    CvNodeValidation(
        node_type="factor-value",
        has_value=True,
        min=0,
        validations=[
            CvTermValidation(
                node_type="factor-value",
                validation=AllowAnyCvTerm(
                    allowed_other_sources=["wikidata", "ILX"],
                    allowed_placeholder_values=[CvTermPlaceholder()],
                ),
            ),
            CvTermValidation(
                node_type="factor-value",
                validation=AllowedCvList(
                    source_names=["DOID", "HP", "MP", "SNOMED"],
                    allowed_other_sources=["wikidata", "ILX"],
                ),
                condition=[
                    FilterCondition(
                        name="Disease",
                        relationship_name="has-instance",
                        start_node_type="factor-definition",
                        expression="factor_type_ref.accession",
                        expression_value="EFO:0000408",
                    )
                ],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="factor-value",
                relationship_name="instance-of",
                reverse_relationship_name="has-instance",
                target="factor-definition",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="factor-value",
                relationship_name="value-of",
                reverse_relationship_name="has-factor-value",
                target="sample",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="factor-value",
                relationship_name="value-of",
                reverse_relationship_name="has-factor-value",
                target="specimen",
                min=0,
                min_for_each_source=1,
            ),
            RelationshipValidation(
                source="factor-value",
                relationship_name="value-of",
                reverse_relationship_name="has-factor-value",
                target="subject",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    CvNodeValidation(
        node_type="metabolite-identifier",
        min=0,
        validations=[
            CvTermValidation(
                node_type="metabolite-identifier",
                validation=AllowedChildrenCvTerms(
                    parent_cv_terms=[
                        ParentCvTerm(
                            cv_term=CvTerm(
                                source="CHEMINF",
                                accession="CHEMINF:000464",
                                name="chemical database identifier",
                            ),
                            index_cv_terms=False,
                        )
                    ]
                ),
                condition=[
                    FilterCondition(
                        name="Reported Metabolite Identifier",
                        relationship_name="identified-as",
                        start_node_type="metabolite",
                    )
                ],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="metabolite-identifier",
                relationship_name="reported-identifier-of",
                reverse_relationship_name="identified-as",
                target="metabolite",
                min=0,
                min_for_each_source=1,
            ),
        ],
    ),
    CvNodeValidation(
        node_type="parameter-type",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="parameter-type",
                node_property_name="name",
                contraints=PropertyConstraint(required=True),
            ),
            CvTermValidation(
                node_type="parameter-type",
                validation=AllowedCvTerms(
                    cv_terms=list(COMMON_PARAMETER_DEFINITIONS.values()),
                    allowed_other_sources=["wikidata", "ILX"],
                ),
            ),
            CvTermValidation(
                node_type="parameter-type",
                validation=AllowedCvTerms(
                    cv_terms=list(COMMON_PROTOCOL_PARAMETERS["CHMO:0000470"].values())
                ),
                condition=[
                    FilterCondition(
                        name="Mass spectrometry protocol",
                        relationship_name="[embedded].parameter_type_ref",
                        start_node_type="parameter-definition",
                        expression="[used-in].protocol_type_ref.accession",
                        expression_value="CHMO:0000470",
                    ),
                ],
            ),
            CvTermValidation(
                node_type="parameter-type",
                validation=AllowedCvTerms(
                    cv_terms=list(COMMON_PROTOCOL_PARAMETERS["CHMO:0001000"].values())
                ),
                condition=[
                    FilterCondition(
                        name="Chromatography protocol",
                        relationship_name="[embedded].parameter_definition_refs.parameter_type_ref",
                        start_node_type="protocol",
                        expression="protocol_type_ref.accession",
                        expression_value="CHMO:0001000",
                    )
                ],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="parameter-type",
                relationship_name="type-of",
                reverse_relationship_name="has-type",
                target="parameter-definition",
                min=0,
                min_for_each_source=0,
            ),
        ],
    ),
    CvNodeValidation(
        node_type="parameter-value",
        has_value=True,
        min=0,
        validations=[
            CvTermValidation(
                node_type="parameter-value",
                validation=AllowAnyCvTerm(
                    allowed_placeholder_values=[CvTermPlaceholder()],
                    allowed_other_sources=["wikidata", "ILX"],
                ),
            ),
            CvTermValidation(
                node_type="parameter-value",
                validation=AllowedChildrenCvTerms(
                    parent_cv_terms=[
                        ParentCvTerm(
                            cv_term=CvTerm(
                                source="MS",
                                accession="MS:1000031",
                                name="instrument model",
                            ),
                            excluded_cv_terms=[
                                CvTerm(
                                    source="MS",
                                    accession="MS:1000491",
                                    name="Dionex instrument model",
                                ),
                                CvTerm(
                                    source="MS",
                                    accession="MS:1000488",
                                    name="Hitachi instrument model",
                                ),
                            ],
                            allow_only_leaf=True,
                        ),
                    ]
                ),
                condition=[
                    FilterCondition(
                        name="Mass spectrometry instrument",
                        relationship_name="has-instance",
                        start_node_type="parameter-definition",
                        expression="parameter_type_ref.accession",
                        expression_value="MSIO:0000171",
                    )
                ],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="parameter-value",
                relationship_name="instance-of",
                reverse_relationship_name="has-instance",
                target="parameter-definition",
                min=0,
                min_for_each_source=1,
            ),
        ],
    ),
    CvNodeValidation(
        node_type="protocol-type",
        min=0,
        validations=[
            NodePropertyValidation(
                node_type="protocol-type",
                node_property_name="name",
                contraints=PropertyConstraint(required=True),
            ),
            CvTermValidation(
                node_type="protocol-type",
                validation=AllowedCvTerms(
                    cv_terms=list(COMMON_PROTOCOLS.values()),
                    allowed_other_sources=["wikidata", "ILX"],
                ),
                condition=[
                    FilterCondition(
                        name="Protocol Type",
                        relationship_name="[embedded].protocol_type_ref",
                        start_node_type="protocol",
                        expression="protocol_type_ref",
                    )
                ],
            ),
        ],
        relationships=[
            RelationshipValidation(
                source="protocol-type",
                relationship_name="type-of",
                reverse_relationship_name="has-type",
                target="protocol",
                min=0,
                min_for_each_source=1,
            ),
        ],
    ),
]

MHD_BASE_VALIDATION_V0_1.mhd_nodes.sort(key=lambda x: x.node_type)

MHD_BASE_VALIDATION_V0_1.cv_nodes.sort(key=lambda x: x.node_type)
