from __future__ import annotations
from collections.abc import Callable
from typing import Any
from .fable_modules.arctrl_python.JsonIO.ldobject import ARCtrl_ROCrate_LDGraph__LDGraph_ToROCrateJsonString_71136F3F
from .fable_modules.arctrl_rocrate.ldcontext import LDContext
from .fable_modules.arctrl_rocrate.ldobject import (LDNode, LDNode_reflection, LDRef, LDGraph)
from .fable_modules.arctrl_rocrate.LDTypes.creative_work import LDCreativeWork
from .fable_modules.arctrl_rocrate.LDTypes.dataset import LDDataset
from .fable_modules.arctrl_rocrate.LDTypes.defined_term import LDDefinedTerm
from .fable_modules.arctrl_rocrate.LDTypes.file import LDFile
from .fable_modules.arctrl_rocrate.LDTypes.lab_protocol import LDLabProtocol
from .fable_modules.arctrl_rocrate.LDTypes.organization import LDOrganization
from .fable_modules.arctrl_rocrate.LDTypes.person import LDPerson
from .fable_modules.arctrl_rocrate.rocrate_context import init_v1_2
from .fable_modules.fable_library.date import utc_now
from .fable_modules.fable_library.list import (FSharpList, length)
from .fable_modules.fable_library.option import (value as value_2, default_arg)
from .fable_modules.fable_library.reflection import (TypeInfo, class_type)
from .fable_modules.fable_library.seq import (to_list, delay, collect, append, singleton, map)
from .fable_modules.fable_library.seq2 import List_distinct
from .fable_modules.fable_library.types import (FSharpRef, Array)
from .fable_modules.fable_library.util import (IEnumerable_1, equals, safe_hash)

def _expr4100() -> TypeInfo:
    return class_type("ROCratePCC.CustomResourceDescriptor", None, CustomResourceDescriptor)


class CustomResourceDescriptor:
    def __init__(self, id: str, role: str) -> None:
        self.id: str = id
        self.role: str = role

    @property
    def Id(self, __unit: None=None) -> str:
        this: CustomResourceDescriptor = self
        return this.id

    @property
    def Role(self, __unit: None=None) -> str:
        this: CustomResourceDescriptor = self
        return this.role


CustomResourceDescriptor_reflection = _expr4100

def CustomResourceDescriptor__ctor_Z384F8060(id: str, role: str) -> CustomResourceDescriptor:
    return CustomResourceDescriptor(id, role)


def ResourceDescriptorType__get_ID(this: ResourceDescriptorType) -> str:
    if this == "constraint":
        return "#hasConstraint"

    elif this == "guidance":
        return "#hasGuidance"

    elif this == "example":
        return "#hasExample"

    elif isinstance(this, CustomResourceDescriptor):
        return this.Id

    else: 
        return "#hasSpecification"



def ResourceDescriptorType__get_Role(this: ResourceDescriptorType) -> str:
    if this == "constraint":
        return "http://www.w3.org/ns/dx/prof/role/constraints"

    elif this == "guidance":
        return "http://www.w3.org/ns/dx/prof/role/guidance"

    elif this == "example":
        return "http://www.w3.org/ns/dx/prof/role/example"

    elif isinstance(this, CustomResourceDescriptor):
        return this.Role

    else: 
        return "http://www.w3.org/ns/dx/prof/role/specification"



def _expr4101() -> TypeInfo:
    return class_type("ROCratePCC.Organization", None, Organization, LDNode_reflection())


class Organization(LDNode):
    def __init__(self, name: str, url: str | None=None, address: str | None=None, department: Organization | None=None, orcid: Any | None=None) -> None:
        super().__init__(value_2(url) if (url is not None) else (("#" + name) + ""), [LDOrganization.schema_type()])
        n: FSharpRef[Organization] = FSharpRef(None)
        n.contents = self
        self.init_004042: int = 1
        LDDataset.set_name_as_string(n.contents, name)
        if url is not None:
            LDDataset.set_url_as_string(n.contents, value_2(url))

        if address is not None:
            n.contents.SetProperty("http://schema.org/address", value_2(address))

        if department is not None:
            n.contents.SetProperty("http://schema.org/department", value_2(department))



Organization_reflection = _expr4101

def Organization__ctor_Z4D24BC84(name: str, url: str | None=None, address: str | None=None, department: Organization | None=None, orcid: Any | None=None) -> Organization:
    return Organization(name, url, address, department, orcid)


def _expr4102() -> TypeInfo:
    return class_type("ROCratePCC.Author", None, Author, LDNode_reflection())


class Author(LDNode):
    def __init__(self, orcid: str, name: str | None=None, given_name: str | None=None, family_name: str | None=None, email: str | None=None, affiliation: Organization | None=None) -> None:
        super().__init__(("https://orcid.org/" + orcid) + "", [LDPerson.schema_type()])
        n: FSharpRef[Author] = FSharpRef(None)
        n.contents = self
        self.init_004052_002D1: int = 1
        if name is not None:
            LDDataset.set_name_as_string(n.contents, value_2(name))

        if affiliation is not None:
            LDPerson.set_affiliation(n.contents, value_2(affiliation))

        if given_name is not None:
            LDPerson.set_given_name_as_string(n.contents, value_2(given_name))

        if family_name is not None:
            LDPerson.set_family_name_as_string(n.contents, value_2(family_name))

        if email is not None:
            LDPerson.set_email_as_string(n.contents, value_2(email))



Author_reflection = _expr4102

def Author__ctor_Z56C7F91C(orcid: str, name: str | None=None, given_name: str | None=None, family_name: str | None=None, email: str | None=None, affiliation: Organization | None=None) -> Author:
    return Author(orcid, name, given_name, family_name, email, affiliation)


def _expr4103() -> TypeInfo:
    return class_type("ROCratePCC.UsedType", None, UsedType, LDNode_reflection())


class UsedType(LDNode):
    def __init__(self, iri: str, name: str, term_code: Any | None=None) -> None:
        super().__init__(iri, [LDDefinedTerm.schema_type()])
        n: FSharpRef[UsedType] = FSharpRef(None)
        n.contents = self
        self.init_004065_002D2: int = 1
        LDDataset.set_name_as_string(n.contents, name)
        if term_code is not None:
            n.contents.SetProperty("https://schema.org/termCode", value_2(term_code))



UsedType_reflection = _expr4103

def UsedType__ctor_Z6EEF448(iri: str, name: str, term_code: Any | None=None) -> UsedType:
    return UsedType(iri, name, term_code)


def _expr4104() -> TypeInfo:
    return class_type("ROCratePCC.License", None, License, LDNode_reflection())


class License(LDNode):
    def __init__(self, iri: str, name: str) -> None:
        super().__init__(iri, [LDCreativeWork.schema_type()])
        n: FSharpRef[License] = FSharpRef(None)
        n.contents = self
        self.init_004074_002D3: int = 1
        LDDataset.set_name_as_string(n.contents, name)


License_reflection = _expr4104

def License__ctor_Z384F8060(iri: str, name: str) -> License:
    return License(iri, name)


def _expr4105() -> TypeInfo:
    return class_type("ROCratePCC.TextualResource", None, TextualResource, LDNode_reflection())


class TextualResource(LDNode):
    def __init__(self, name: str, file_path: str, encoding_format: str, root_data_entity_id: str | None=None) -> None:
        super().__init__(file_path, [LDFile.schema_type()])
        n: FSharpRef[TextualResource] = FSharpRef(None)
        n.contents = self
        self.init_004079_002D4: int = 1
        LDDataset.set_name_as_string(n.contents, name)
        LDFile.set_encoding_format_as_string(n.contents, encoding_format)
        if root_data_entity_id is None:
            pass

        else: 
            id: str = root_data_entity_id
            n.contents.SetProperty(LDFile.about(), LDRef(id))



TextualResource_reflection = _expr4105

def TextualResource__ctor_5978D483(name: str, file_path: str, encoding_format: str, root_data_entity_id: str | None=None) -> TextualResource:
    return TextualResource(name, file_path, encoding_format, root_data_entity_id)


def _expr4106() -> TypeInfo:
    return class_type("ROCratePCC.ResourceDescriptor", None, ResourceDescriptor, LDNode_reflection())


class ResourceDescriptor(LDNode):
    def __init__(self, textual_resources: Array[TextualResource], resource_descriptor_type: ResourceDescriptorType) -> None:
        super().__init__(ResourceDescriptorType__get_ID(resource_descriptor_type), ["http://www.w3.org/ns/dx/prof/ResourceDescriptor"])
        n: FSharpRef[ResourceDescriptor] = FSharpRef(None)
        n.contents = self
        self.init_004090_002D5: int = 1
        n.contents.SetProperty("http://www.w3.org/ns/dx/prof/hasRole", LDRef(ResourceDescriptorType__get_Role(resource_descriptor_type)))
        n.contents.SetProperty("http://www.w3.org/ns/dx/prof/hasArtifact", textual_resources)


ResourceDescriptor_reflection = _expr4106

def ResourceDescriptor__ctor_40E96EF7(textual_resources: Array[TextualResource], resource_descriptor_type: ResourceDescriptorType) -> ResourceDescriptor:
    return ResourceDescriptor(textual_resources, resource_descriptor_type)


def _expr4107() -> TypeInfo:
    return class_type("ROCratePCC.Specification", None, Specification, ResourceDescriptor_reflection())


class Specification(ResourceDescriptor):
    def __init__(self, textual_resources: Array[TextualResource]) -> None:
        super().__init__(textual_resources, "specification")
        self.init_004099_002D6: int = 1


Specification_reflection = _expr4107

def Specification__ctor_Z715ED06F(textual_resources: Array[TextualResource]) -> Specification:
    return Specification(textual_resources)


def _expr4108() -> TypeInfo:
    return class_type("ROCratePCC.Constraint", None, Constraint, ResourceDescriptor_reflection())


class Constraint(ResourceDescriptor):
    def __init__(self, textual_resources: Array[TextualResource]) -> None:
        super().__init__(textual_resources, "constraint")
        self.init_0040103_002D7: int = 1


Constraint_reflection = _expr4108

def Constraint__ctor_Z715ED06F(textual_resources: Array[TextualResource]) -> Constraint:
    return Constraint(textual_resources)


def _expr4109() -> TypeInfo:
    return class_type("ROCratePCC.Guidance", None, Guidance, ResourceDescriptor_reflection())


class Guidance(ResourceDescriptor):
    def __init__(self, textual_resources: Array[TextualResource]) -> None:
        super().__init__(textual_resources, "guidance")
        self.init_0040107_002D8: int = 1


Guidance_reflection = _expr4109

def Guidance__ctor_Z715ED06F(textual_resources: Array[TextualResource]) -> Guidance:
    return Guidance(textual_resources)


def _expr4110() -> TypeInfo:
    return class_type("ROCratePCC.Example", None, Example, ResourceDescriptor_reflection())


class Example(ResourceDescriptor):
    def __init__(self, textual_resources: Array[TextualResource]) -> None:
        super().__init__(textual_resources, "example")
        self.init_0040111_002D9: int = 1


Example_reflection = _expr4110

def Example__ctor_Z715ED06F(textual_resources: Array[TextualResource]) -> Example:
    return Example(textual_resources)


def _expr4118() -> TypeInfo:
    return class_type("ROCratePCC.RootDataEntity", None, RootDataEntity, LDNode_reflection())


class RootDataEntity(LDNode):
    def __init__(self, id: str, name: str, description: str, license: License, authors: Array[Author], version: str | None=None, keywords: Array[str] | None=None, used_types: Array[UsedType] | None=None, resource_descriptors: Array[ResourceDescriptor] | None=None, data_published: Any | None=None, publisher: Organization | None=None) -> None:
        super().__init__(id, [LDDataset.schema_type(), "http://www.w3.org/ns/dx/prof/Profile"])
        n: FSharpRef[RootDataEntity] = FSharpRef(None)
        n.contents = self
        self.init_0040115_002D10: int = 1
        def _arrow4112(__unit: None=None) -> IEnumerable_1[LDNode]:
            def _arrow4111(rd: ResourceDescriptor) -> IEnumerable_1[LDNode]:
                return rd.GetPropertyNodes("http://www.w3.org/ns/dx/prof/hasArtifact")

            return collect(_arrow4111, default_arg(resource_descriptors, []))

        textual_resources: Array[LDNode] = list(to_list(delay(_arrow4112)))
        def _arrow4116(__unit: None=None) -> IEnumerable_1[LDNode]:
            def _arrow4115(tr: LDNode) -> IEnumerable_1[LDNode]:
                def _arrow4114(__unit: None=None) -> IEnumerable_1[LDNode]:
                    def _arrow4113(ut: UsedType) -> LDNode:
                        return ut

                    return map(_arrow4113, default_arg(used_types, []))

                return append(singleton(tr), delay(_arrow4114))

            return collect(_arrow4115, textual_resources)

        class ObjectExpr4117:
            @property
            def Equals(self) -> Callable[[LDNode, LDNode], bool]:
                return equals

            @property
            def GetHashCode(self) -> Callable[[LDNode], int]:
                return safe_hash

        has_parts: FSharpList[LDNode] = List_distinct(to_list(delay(_arrow4116)), ObjectExpr4117())
        LDDataset.set_license_as_creative_work(n.contents, license)
        LDDataset.set_name_as_string(n.contents, name)
        LDDataset.set_description_as_string(n.contents, description)
        n.contents.SetProperty("http://schema.org/author", authors)
        if keywords is not None:
            n.contents.SetProperty("http://schema.org/keywords", value_2(keywords))

        if version is not None:
            LDLabProtocol.set_version_as_string(n.contents, value_2(version))

        if length(has_parts) > 0:
            LDDataset.set_has_parts(n.contents, list(has_parts))

        if resource_descriptors is not None:
            n.contents.SetProperty("http://www.w3.org/ns/dx/prof/hasResource", value_2(resource_descriptors))

        if data_published is not None:
            LDDataset.set_date_published_as_date_time(n.contents, value_2(data_published))

        else: 
            LDDataset.set_date_published_as_date_time(n.contents, utc_now())

        if publisher is not None:
            n.contents.SetProperty("http://schema.org/publisher", value_2(publisher))



RootDataEntity_reflection = _expr4118

def RootDataEntity__ctor_64728AC0(id: str, name: str, description: str, license: License, authors: Array[Author], version: str | None=None, keywords: Array[str] | None=None, used_types: Array[UsedType] | None=None, resource_descriptors: Array[ResourceDescriptor] | None=None, data_published: Any | None=None, publisher: Organization | None=None) -> RootDataEntity:
    return RootDataEntity(id, name, description, license, authors, version, keywords, used_types, resource_descriptors, data_published, publisher)


def _expr4128() -> TypeInfo:
    return class_type("ROCratePCC.Profile", None, Profile, LDNode_reflection())


class Profile(LDNode):
    def __init__(self, root_data_entity: RootDataEntity, license: License | None=None, ro_crate_spec: str | None=None) -> None:
        super().__init__("ro-crate-metadata.json", [LDCreativeWork.schema_type()])
        n: FSharpRef[Profile] = FSharpRef(None)
        n.contents = self
        self.init_0040142_002D11: int = 1
        LDDataset.set_abouts(n.contents, [root_data_entity])
        if license is not None:
            LDDataset.set_license_as_creative_work(n.contents, value_2(license))

        ro_crate_spec_1: str = default_arg(ro_crate_spec, "https://w3id.org/ro/crate/1.2")
        root_data_entity.SetProperty("http://www.w3.org/ns/dx/prof/isProfileOf", ro_crate_spec_1)
        n.contents.SetProperty("http://purl.org/dc/terms/conformsTo", ro_crate_spec_1)

    def ToROCrateJsonString(self, spaces: int | None=None) -> str:
        this: Profile = self
        context: LDContext = init_v1_2()
        this.Compact_InPlace(context, False)
        graph: LDGraph = this.Flatten()
        graph.SetContext(context)
        return ARCtrl_ROCrate_LDGraph__LDGraph_ToROCrateJsonString_71136F3F(graph, spaces)


Profile_reflection = _expr4128

def Profile__ctor_6B2DF90D(root_data_entity: RootDataEntity, license: License | None=None, ro_crate_spec: str | None=None) -> Profile:
    return Profile(root_data_entity, license, ro_crate_spec)


__all__ = ["CustomResourceDescriptor_reflection", "ResourceDescriptorType__get_ID", "ResourceDescriptorType__get_Role", "Organization_reflection", "Author_reflection", "UsedType_reflection", "License_reflection", "TextualResource_reflection", "ResourceDescriptor_reflection", "Specification_reflection", "Constraint_reflection", "Guidance_reflection", "Example_reflection", "RootDataEntity_reflection", "Profile_reflection"]

