# -*- coding: utf-8 -*-
"""
Profile: http://hl7.org/fhir/StructureDefinition/GraphDefinition
Release: STU3
Version: 3.0.2
Revision: 11917
Last updated: 2019-10-24T11:53:00+11:00
"""
import typing

from pydantic import Field

from . import backboneelement, domainresource, fhirtypes


class GraphDefinition(domainresource.DomainResource):
    """Disclaimer: Any field name ends with ``__ext`` doesn't part of
    Resource StructureDefinition, instead used to enable Extensibility feature
    for FHIR Primitive Data Types.

    Definition of an graph of resources.
    A formal computable definition of a graph of resources - that is, a
    coherent set of resources that form a graph by following references. The
    Graph Definition resource defines a set and makes rules about the set.
    """

    __resource_type__ = "GraphDefinition"

    contact: typing.List[fhirtypes.ContactDetailType] = Field(  # type: ignore
        None,
        alias="contact",
        title="Contact details for the publisher",
        description=(
            "Contact details to assist a user in finding and communicating with the"
            " publisher."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    date: fhirtypes.DateTimeType = Field(  # type: ignore
        None,
        alias="date",
        title="Date this was last changed",
        description=(
            "The date  (and optionally time) when the graph definition was "
            "published. The date must change if and when the business version "
            "changes and it must change if the status code changes. In addition, it"
            " should change when the substantive content of the graph definition "
            "changes."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )
    date__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_date", title="Extension field for ``date``."
    )

    description: fhirtypes.MarkdownType = Field(  # type: ignore
        None,
        alias="description",
        title="Natural language description of the graph definition",
        description=(
            "A free text natural language description of the graph definition from "
            "a consumer's perspective."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )
    description__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_description", title="Extension field for ``description``."
    )

    experimental: bool = Field(  # type: ignore
        None,
        alias="experimental",
        title="For testing purposes, not real usage",
        description=(
            "A boolean value to indicate that this graph definition is authored for"
            " testing purposes (or education/evaluation/marketing), and is not "
            "intended to be used for genuine usage."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )
    experimental__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_experimental", title="Extension field for ``experimental``."
    )

    jurisdiction: typing.List[fhirtypes.CodeableConceptType] = Field(  # type: ignore
        None,
        alias="jurisdiction",
        title="Intended jurisdiction for graph definition (if applicable)",
        description=(
            "A legal or geographic region in which the graph definition is intended"
            " to be used."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    link: typing.List[fhirtypes.GraphDefinitionLinkType] = Field(  # type: ignore
        None,
        alias="link",
        title="Links this graph makes rules about",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )

    name: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="name",
        title="Name for this graph definition (computer friendly)",
        description=(
            "A natural language name identifying the graph definition. This name "
            "should be usable as an identifier for the module by machine processing"
            " applications such as code generation."
        ),
        json_schema_extra={
            "element_property": True,
            "element_required": True,
        },
    )
    name__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_name", title="Extension field for ``name``."
    )

    profile: fhirtypes.UriType = Field(  # type: ignore
        None,
        alias="profile",
        title="Profile on base resource",
        description="The profile that describes the use of the base resource.",
        json_schema_extra={
            "element_property": True,
        },
    )
    profile__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_profile", title="Extension field for ``profile``."
    )

    publisher: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="publisher",
        title="Name of the publisher (organization or individual)",
        description=(
            "The name of the individual or organization that published the graph "
            "definition."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )
    publisher__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_publisher", title="Extension field for ``publisher``."
    )

    purpose: fhirtypes.MarkdownType = Field(  # type: ignore
        None,
        alias="purpose",
        title="Why this graph definition is defined",
        description=(
            "Explaination of why this graph definition is needed and why it has "
            "been designed as it has."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )
    purpose__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_purpose", title="Extension field for ``purpose``."
    )

    start: fhirtypes.CodeType = Field(  # type: ignore
        None,
        alias="start",
        title="Type of resource at which the graph starts",
        description="The type of FHIR resource at which instances of this graph start.",
        json_schema_extra={
            "element_property": True,
            "element_required": True,
        },
    )
    start__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_start", title="Extension field for ``start``."
    )

    status: fhirtypes.CodeType = Field(  # type: ignore
        None,
        alias="status",
        title="draft | active | retired | unknown",
        description=(
            "The status of this graph definition. Enables tracking the life-cycle "
            "of the content."
        ),
        json_schema_extra={
            "element_property": True,
            "element_required": True,
            # note: Enum values can be used in validation,
            # but use in your own responsibilities, read official FHIR documentation.
            "enum_values": ["draft", "active", "retired", "unknown"],
        },
    )
    status__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_status", title="Extension field for ``status``."
    )

    url: fhirtypes.UriType = Field(  # type: ignore
        None,
        alias="url",
        title="Logical URI to reference this graph definition (globally unique)",
        description=(
            "An absolute URI that is used to identify this graph definition when it"
            " is referenced in a specification, model, design or an instance. This "
            "SHALL be a URL, SHOULD be globally unique, and SHOULD be an address at"
            " which this graph definition is (or will be) published. The URL SHOULD"
            " include the major version of the graph definition. For more "
            "information see [Technical and Business "
            "Versions](resource.html#versions)."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )
    url__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_url", title="Extension field for ``url``."
    )

    useContext: typing.List[fhirtypes.UsageContextType] = Field(  # type: ignore
        None,
        alias="useContext",
        title="Context the content is intended to support",
        description=(
            "The content was developed with a focus and intent of supporting the "
            "contexts that are listed. These terms may be used to assist with "
            "indexing and searching for appropriate graph definition instances."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    version: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="version",
        title="Business version of the graph definition",
        description=(
            "The identifier that is used to identify this version of the graph "
            "definition when it is referenced in a specification, model, design or "
            "instance. This is an arbitrary value managed by the graph definition "
            "author and is not expected to be globally unique. For example, it "
            "might be a timestamp (e.g. yyyymmdd) if a managed version is not "
            "available. There is also no expectation that versions can be placed in"
            " a lexicographical sequence."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )
    version__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_version", title="Extension field for ``version``."
    )

    @classmethod
    def elements_sequence(cls):
        """returning all elements names from
        ``GraphDefinition`` according specification,
        with preserving original sequence order.
        """
        return [
            "id",
            "meta",
            "implicitRules",
            "language",
            "text",
            "contained",
            "extension",
            "modifierExtension",
            "url",
            "version",
            "name",
            "status",
            "experimental",
            "date",
            "publisher",
            "contact",
            "description",
            "useContext",
            "jurisdiction",
            "purpose",
            "start",
            "profile",
            "link",
        ]

    def get_required_fields(self) -> typing.List[typing.Tuple[str, str]]:
        """https://www.hl7.org/fhir/extensibility.html#Special-Case
        In some cases, implementers might find that they do not have appropriate data for
        an element with minimum cardinality = 1. In this case, the element must be present,
        but unless the resource or a profile on it has made the actual value of the primitive
        data type mandatory, it is possible to provide an extension that explains why
        the primitive value is not present.
        """
        required_fields = [
            ("name", "name__ext"),
            ("start", "start__ext"),
            ("status", "status__ext"),
        ]
        return required_fields


class GraphDefinitionLink(backboneelement.BackboneElement):
    """Disclaimer: Any field name ends with ``__ext`` doesn't part of
    Resource StructureDefinition, instead used to enable Extensibility feature
    for FHIR Primitive Data Types.

    Links this graph makes rules about.
    """

    __resource_type__ = "GraphDefinitionLink"

    description: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="description",
        title="Why this link is specified",
        description=(
            "Information about why this link is of interest in this graph "
            "definition."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )
    description__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_description", title="Extension field for ``description``."
    )

    max: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="max",
        title="Maximum occurrences for this link",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )
    max__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_max", title="Extension field for ``max``."
    )

    min: fhirtypes.IntegerType = Field(  # type: ignore
        None,
        alias="min",
        title="Minimum occurrences for this link",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )
    min__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_min", title="Extension field for ``min``."
    )

    path: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="path",
        title="Path in the resource that contains the link",
        description=None,
        json_schema_extra={
            "element_property": True,
            "element_required": True,
        },
    )
    path__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_path", title="Extension field for ``path``."
    )

    sliceName: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="sliceName",
        title="Which slice (if profiled)",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )
    sliceName__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_sliceName", title="Extension field for ``sliceName``."
    )

    target: typing.List[fhirtypes.GraphDefinitionLinkTargetType] = Field(  # type: ignore
        ...,
        alias="target",
        title="Potential target for the link",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )

    @classmethod
    def elements_sequence(cls):
        """returning all elements names from
        ``GraphDefinitionLink`` according specification,
        with preserving original sequence order.
        """
        return [
            "id",
            "extension",
            "modifierExtension",
            "path",
            "sliceName",
            "min",
            "max",
            "description",
            "target",
        ]

    def get_required_fields(self) -> typing.List[typing.Tuple[str, str]]:
        """https://www.hl7.org/fhir/extensibility.html#Special-Case
        In some cases, implementers might find that they do not have appropriate data for
        an element with minimum cardinality = 1. In this case, the element must be present,
        but unless the resource or a profile on it has made the actual value of the primitive
        data type mandatory, it is possible to provide an extension that explains why
        the primitive value is not present.
        """
        required_fields = [("path", "path__ext")]
        return required_fields


class GraphDefinitionLinkTarget(backboneelement.BackboneElement):
    """Disclaimer: Any field name ends with ``__ext`` doesn't part of
    Resource StructureDefinition, instead used to enable Extensibility feature
    for FHIR Primitive Data Types.

    Potential target for the link.
    """

    __resource_type__ = "GraphDefinitionLinkTarget"

    compartment: typing.List[fhirtypes.GraphDefinitionLinkTargetCompartmentType] = Field(  # type: ignore
        None,
        alias="compartment",
        title="Compartment Consistency Rules",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )

    link: typing.List[fhirtypes.GraphDefinitionLinkType] = Field(  # type: ignore
        None,
        alias="link",
        title="Additional links from target resource",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )

    profile: fhirtypes.UriType = Field(  # type: ignore
        None,
        alias="profile",
        title="Profile for the target resource",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )
    profile__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_profile", title="Extension field for ``profile``."
    )

    type: fhirtypes.CodeType = Field(  # type: ignore
        None,
        alias="type",
        title="Type of resource this link refers to",
        description=None,
        json_schema_extra={
            "element_property": True,
            "element_required": True,
        },
    )
    type__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_type", title="Extension field for ``type``."
    )

    @classmethod
    def elements_sequence(cls):
        """returning all elements names from
        ``GraphDefinitionLinkTarget`` according specification,
        with preserving original sequence order.
        """
        return [
            "id",
            "extension",
            "modifierExtension",
            "type",
            "profile",
            "compartment",
            "link",
        ]

    def get_required_fields(self) -> typing.List[typing.Tuple[str, str]]:
        """https://www.hl7.org/fhir/extensibility.html#Special-Case
        In some cases, implementers might find that they do not have appropriate data for
        an element with minimum cardinality = 1. In this case, the element must be present,
        but unless the resource or a profile on it has made the actual value of the primitive
        data type mandatory, it is possible to provide an extension that explains why
        the primitive value is not present.
        """
        required_fields = [("type", "type__ext")]
        return required_fields


class GraphDefinitionLinkTargetCompartment(backboneelement.BackboneElement):
    """Disclaimer: Any field name ends with ``__ext`` doesn't part of
    Resource StructureDefinition, instead used to enable Extensibility feature
    for FHIR Primitive Data Types.

    Compartment Consistency Rules.
    """

    __resource_type__ = "GraphDefinitionLinkTargetCompartment"

    code: fhirtypes.CodeType = Field(  # type: ignore
        None,
        alias="code",
        title="Identifies the compartment",
        description=None,
        json_schema_extra={
            "element_property": True,
            "element_required": True,
        },
    )
    code__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_code", title="Extension field for ``code``."
    )

    description: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="description",
        title="Documentation for FHIRPath expression",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )
    description__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_description", title="Extension field for ``description``."
    )

    expression: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="expression",
        title="Custom rule, as a FHIRPath expression",
        description=None,
        json_schema_extra={
            "element_property": True,
        },
    )
    expression__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_expression", title="Extension field for ``expression``."
    )

    rule: fhirtypes.CodeType = Field(  # type: ignore
        None,
        alias="rule",
        title="identical | matching | different | custom",
        description="identical | matching | different | no-rule | custom.",
        json_schema_extra={
            "element_property": True,
            "element_required": True,
            # note: Enum values can be used in validation,
            # but use in your own responsibilities, read official FHIR documentation.
            "enum_values": ["identical", "matching", "different", "custom"],
        },
    )
    rule__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_rule", title="Extension field for ``rule``."
    )

    @classmethod
    def elements_sequence(cls):
        """returning all elements names from
        ``GraphDefinitionLinkTargetCompartment`` according specification,
        with preserving original sequence order.
        """
        return [
            "id",
            "extension",
            "modifierExtension",
            "code",
            "rule",
            "expression",
            "description",
        ]

    def get_required_fields(self) -> typing.List[typing.Tuple[str, str]]:
        """https://www.hl7.org/fhir/extensibility.html#Special-Case
        In some cases, implementers might find that they do not have appropriate data for
        an element with minimum cardinality = 1. In this case, the element must be present,
        but unless the resource or a profile on it has made the actual value of the primitive
        data type mandatory, it is possible to provide an extension that explains why
        the primitive value is not present.
        """
        required_fields = [("code", "code__ext"), ("rule", "rule__ext")]
        return required_fields
