# -*- coding: utf-8 -*-
"""
Profile: http://hl7.org/fhir/StructureDefinition/DocumentReference
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 DocumentReference(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.

    A reference to a document.
    """

    __resource_type__ = "DocumentReference"

    authenticator: fhirtypes.ReferenceType = Field(  # type: ignore
        None,
        alias="authenticator",
        title="Who/what authenticated the document",
        description=(
            "Which person or organization authenticates that this document is " "valid."
        ),
        json_schema_extra={
            "element_property": True,
            # note: Listed Resource Type(s) should be allowed as Reference.
            "enum_reference_types": ["Practitioner", "Organization"],
        },
    )

    author: typing.List[fhirtypes.ReferenceType] = Field(  # type: ignore
        None,
        alias="author",
        title="Who and/or what authored the document",
        description=(
            "Identifies who is responsible for adding the information to the "
            "document."
        ),
        json_schema_extra={
            "element_property": True,
            # note: Listed Resource Type(s) should be allowed as Reference.
            "enum_reference_types": [
                "Practitioner",
                "Organization",
                "Device",
                "Patient",
                "RelatedPerson",
            ],
        },
    )

    class_fhir: fhirtypes.CodeableConceptType = Field(  # type: ignore
        None,
        alias="class",
        title="Categorization of document",
        description=(
            "A categorization for the type of document referenced - helps for "
            "indexing and searching. This may be implied by or derived from the "
            "code specified in the DocumentReference.type."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    content: typing.List[fhirtypes.DocumentReferenceContentType] = Field(  # type: ignore
        ...,
        alias="content",
        title="Document referenced",
        description=(
            "The document and format referenced. There may be multiple content "
            "element repetitions, each with a different format."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    context: fhirtypes.DocumentReferenceContextType = Field(  # type: ignore
        None,
        alias="context",
        title="Clinical context of document",
        description="The clinical context in which the document was prepared.",
        json_schema_extra={
            "element_property": True,
        },
    )

    created: fhirtypes.DateTimeType = Field(  # type: ignore
        None,
        alias="created",
        title="Document creation time",
        description="When the document was created.",
        json_schema_extra={
            "element_property": True,
        },
    )
    created__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_created", title="Extension field for ``created``."
    )

    custodian: fhirtypes.ReferenceType = Field(  # type: ignore
        None,
        alias="custodian",
        title="Organization which maintains the document",
        description=(
            "Identifies the organization or group who is responsible for ongoing "
            "maintenance of and access to the document."
        ),
        json_schema_extra={
            "element_property": True,
            # note: Listed Resource Type(s) should be allowed as Reference.
            "enum_reference_types": ["Organization"],
        },
    )

    description: fhirtypes.StringType = Field(  # type: ignore
        None,
        alias="description",
        title="Human-readable description (title)",
        description=(
            "Human-readable description of the source document. This is sometimes "
            'known as the "title".'
        ),
        json_schema_extra={
            "element_property": True,
        },
    )
    description__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_description", title="Extension field for ``description``."
    )

    docStatus: fhirtypes.CodeType = Field(  # type: ignore
        None,
        alias="docStatus",
        title="preliminary | final | appended | amended | entered-in-error",
        description="The status of the underlying document.",
        json_schema_extra={
            "element_property": True,
            # note: Enum values can be used in validation,
            # but use in your own responsibilities, read official FHIR documentation.
            "enum_values": [
                "preliminary",
                "final",
                "appended",
                "amended",
                "entered-in-error",
            ],
        },
    )
    docStatus__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_docStatus", title="Extension field for ``docStatus``."
    )

    identifier: typing.List[fhirtypes.IdentifierType] = Field(  # type: ignore
        None,
        alias="identifier",
        title="Other identifiers for the document",
        description=(
            "Other identifiers associated with the document, including version "
            "independent identifiers."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    indexed: fhirtypes.InstantType = Field(  # type: ignore
        None,
        alias="indexed",
        title="When this document reference was created",
        description="When the document reference was created.",
        json_schema_extra={
            "element_property": True,
            "element_required": True,
        },
    )
    indexed__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_indexed", title="Extension field for ``indexed``."
    )

    masterIdentifier: fhirtypes.IdentifierType = Field(  # type: ignore
        None,
        alias="masterIdentifier",
        title="Master Version Specific Identifier",
        description=(
            "Document identifier as assigned by the source of the document. This "
            "identifier is specific to this version of the document. This unique "
            "identifier may be used elsewhere to identify this version of the "
            "document."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    relatesTo: typing.List[fhirtypes.DocumentReferenceRelatesToType] = Field(  # type: ignore
        None,
        alias="relatesTo",
        title="Relationships to other documents",
        description=(
            "Relationships that this document has with other document references "
            "that already exist."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    securityLabel: typing.List[fhirtypes.CodeableConceptType] = Field(  # type: ignore
        None,
        alias="securityLabel",
        title="Document security-tags",
        description=(
            "A set of Security-Tag codes specifying the level of privacy/security "
            "of the Document. Note that DocumentReference.meta.security contains "
            'the security labels of the "reference" to the document, while '
            "DocumentReference.securityLabel contains a snapshot of the security "
            "labels on the document the reference refers to."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    status: fhirtypes.CodeType = Field(  # type: ignore
        None,
        alias="status",
        title="current | superseded | entered-in-error",
        description="The status of this document reference.",
        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": ["current", "superseded", "entered-in-error"],
        },
    )
    status__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_status", title="Extension field for ``status``."
    )

    subject: fhirtypes.ReferenceType = Field(  # type: ignore
        None,
        alias="subject",
        title="Who/what is the subject of the document",
        description=(
            "Who or what the document is about. The document can be about a person,"
            " (patient or healthcare practitioner), a device (e.g. a machine) or "
            "even a group of subjects (such as a document about a herd of farm "
            "animals, or a set of patients that share a common exposure)."
        ),
        json_schema_extra={
            "element_property": True,
            # note: Listed Resource Type(s) should be allowed as Reference.
            "enum_reference_types": ["Patient", "Practitioner", "Group", "Device"],
        },
    )

    type: fhirtypes.CodeableConceptType = Field(  # type: ignore
        ...,
        alias="type",
        title="Kind of document (LOINC if possible)",
        description=(
            "Specifies the particular kind of document referenced  (e.g. History "
            "and Physical, Discharge Summary, Progress Note). This usually equates "
            "to the purpose of making the document referenced."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    @classmethod
    def elements_sequence(cls):
        """returning all elements names from
        ``DocumentReference`` according specification,
        with preserving original sequence order.
        """
        return [
            "id",
            "meta",
            "implicitRules",
            "language",
            "text",
            "contained",
            "extension",
            "modifierExtension",
            "masterIdentifier",
            "identifier",
            "status",
            "docStatus",
            "type",
            "class",
            "subject",
            "created",
            "indexed",
            "author",
            "authenticator",
            "custodian",
            "relatesTo",
            "description",
            "securityLabel",
            "content",
            "context",
        ]

    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 = [("indexed", "indexed__ext"), ("status", "status__ext")]
        return required_fields


class DocumentReferenceContent(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.

    Document referenced.
    The document and format referenced. There may be multiple content element
    repetitions, each with a different format.
    """

    __resource_type__ = "DocumentReferenceContent"

    attachment: fhirtypes.AttachmentType = Field(  # type: ignore
        ...,
        alias="attachment",
        title="Where to access the document",
        description=(
            "The document or URL of the document along with critical metadata to "
            "prove content has integrity."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    format: fhirtypes.CodingType = Field(  # type: ignore
        None,
        alias="format",
        title="Format/content rules for the document",
        description=(
            "An identifier of the document encoding, structure, and template that "
            "the document conforms to beyond the base format indicated in the "
            "mimeType."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    @classmethod
    def elements_sequence(cls):
        """returning all elements names from
        ``DocumentReferenceContent`` according specification,
        with preserving original sequence order.
        """
        return ["id", "extension", "modifierExtension", "attachment", "format"]


class DocumentReferenceContext(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.

    Clinical context of document.
    The clinical context in which the document was prepared.
    """

    __resource_type__ = "DocumentReferenceContext"

    encounter: fhirtypes.ReferenceType = Field(  # type: ignore
        None,
        alias="encounter",
        title="Context of the document  content",
        description=(
            "Describes the clinical encounter or type of care that the document "
            "content is associated with."
        ),
        json_schema_extra={
            "element_property": True,
            # note: Listed Resource Type(s) should be allowed as Reference.
            "enum_reference_types": ["Encounter"],
        },
    )

    event: typing.List[fhirtypes.CodeableConceptType] = Field(  # type: ignore
        None,
        alias="event",
        title="Main clinical acts documented",
        description=(
            "This list of codes represents the main clinical acts, such as a "
            "colonoscopy or an appendectomy, being documented. In some cases, the "
            'event is inherent in the typeCode, such as a "History and Physical '
            'Report" in which the procedure being documented is necessarily a '
            '"History and Physical" act.'
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    facilityType: fhirtypes.CodeableConceptType = Field(  # type: ignore
        None,
        alias="facilityType",
        title="Kind of facility where patient was seen",
        description="The kind of facility where the patient was seen.",
        json_schema_extra={
            "element_property": True,
        },
    )

    period: fhirtypes.PeriodType = Field(  # type: ignore
        None,
        alias="period",
        title="Time of service that is being documented",
        description=(
            "The time period over which the service that is described by the "
            "document was provided."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    practiceSetting: fhirtypes.CodeableConceptType = Field(  # type: ignore
        None,
        alias="practiceSetting",
        title=(
            "Additional details about where the content was created (e.g. clinical "
            "specialty)"
        ),
        description=(
            "This property may convey specifics about the practice setting where "
            "the content was created, often reflecting the clinical specialty."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    related: typing.List[fhirtypes.DocumentReferenceContextRelatedType] = Field(  # type: ignore
        None,
        alias="related",
        title="Related identifiers or resources",
        description=(
            "Related identifiers or resources associated with the " "DocumentReference."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    sourcePatientInfo: fhirtypes.ReferenceType = Field(  # type: ignore
        None,
        alias="sourcePatientInfo",
        title="Patient demographics from source",
        description=(
            "The Patient Information as known when the document was published. May "
            "be a reference to a version specific, or contained."
        ),
        json_schema_extra={
            "element_property": True,
            # note: Listed Resource Type(s) should be allowed as Reference.
            "enum_reference_types": ["Patient"],
        },
    )

    @classmethod
    def elements_sequence(cls):
        """returning all elements names from
        ``DocumentReferenceContext`` according specification,
        with preserving original sequence order.
        """
        return [
            "id",
            "extension",
            "modifierExtension",
            "encounter",
            "event",
            "period",
            "facilityType",
            "practiceSetting",
            "sourcePatientInfo",
            "related",
        ]


class DocumentReferenceContextRelated(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.

    Related identifiers or resources.
    Related identifiers or resources associated with the DocumentReference.
    """

    __resource_type__ = "DocumentReferenceContextRelated"

    identifier: fhirtypes.IdentifierType = Field(  # type: ignore
        None,
        alias="identifier",
        title="Identifier of related objects or events",
        description=(
            "Related identifier to this DocumentReference. If both id and ref are "
            "present they shall refer to the same thing."
        ),
        json_schema_extra={
            "element_property": True,
        },
    )

    ref: fhirtypes.ReferenceType = Field(  # type: ignore
        None,
        alias="ref",
        title="Related Resource",
        description=(
            "Related Resource to this DocumentReference. If both id and ref are "
            "present they shall refer to the same thing."
        ),
        json_schema_extra={
            "element_property": True,
            # note: Listed Resource Type(s) should be allowed as Reference.
            "enum_reference_types": ["Resource"],
        },
    )

    @classmethod
    def elements_sequence(cls):
        """returning all elements names from
        ``DocumentReferenceContextRelated`` according specification,
        with preserving original sequence order.
        """
        return ["id", "extension", "modifierExtension", "identifier", "ref"]


class DocumentReferenceRelatesTo(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.

    Relationships to other documents.
    Relationships that this document has with other document references that
    already exist.
    """

    __resource_type__ = "DocumentReferenceRelatesTo"

    code: fhirtypes.CodeType = Field(  # type: ignore
        None,
        alias="code",
        title="replaces | transforms | signs | appends",
        description="The type of relationship that this document has with anther document.",
        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": ["replaces", "transforms", "signs", "appends"],
        },
    )
    code__ext: fhirtypes.FHIRPrimitiveExtensionType = Field(  # type: ignore
        None, alias="_code", title="Extension field for ``code``."
    )

    target: fhirtypes.ReferenceType = Field(  # type: ignore
        ...,
        alias="target",
        title="Target of the relationship",
        description="The target document of this relationship.",
        json_schema_extra={
            "element_property": True,
            # note: Listed Resource Type(s) should be allowed as Reference.
            "enum_reference_types": ["DocumentReference"],
        },
    )

    @classmethod
    def elements_sequence(cls):
        """returning all elements names from
        ``DocumentReferenceRelatesTo`` according specification,
        with preserving original sequence order.
        """
        return ["id", "extension", "modifierExtension", "code", "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 = [("code", "code__ext")]
        return required_fields
