"""Support for simplified access to data on nodes of type omni.graph.nodes.WritePrimsV2

Write back bundle(s) containing multiple prims to the stage.
"""

import usdrt

import carb
import omni.graph.core as og
import omni.graph.core._omni_graph_core as _og
import omni.graph.tools.ogn as ogn



class OgnWritePrimsV2Database(og.Database):
    """Helper class providing simplified access to data on nodes of type omni.graph.nodes.WritePrimsV2

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.attrNamesToExport
            inputs.execIn
            inputs.layerIdentifier
            inputs.pathPattern
            inputs.prims
            inputs.primsBundle
            inputs.scatterUnderTargets
            inputs.typePattern
            inputs.usdWriteBack
        Outputs:
            outputs.execOut
        State:
            state.attrNamesToExport
            state.layerIdentifier
            state.pathPattern
            state.primBundleDirtyId
            state.scatterUnderTargets
            state.typePattern
            state.usdWriteBack
    """

    # Imprint the generator and target ABI versions in the file for JIT generation
    GENERATOR_VERSION = (1, 41, 3)
    TARGET_VERSION = (2, 139, 12)

    # This is an internal object that provides per-class storage of a per-node data dictionary
    PER_NODE_DATA = {}

    # This is an internal object that describes unchanging attributes in a generic way
    # The values in this list are in no particular order, as a per-attribute tuple
    #     Name, Type, ExtendedTypeIndex, UiName, Description, Metadata,
    #     Is_Required, DefaultValue, Is_Deprecated, DeprecationMsg
    # You should not need to access any of this data directly, use the defined database interfaces
    INTERFACE = og.Database._get_interface([
        ('inputs:attrNamesToExport', 'string', 0, 'Attribute Name Pattern', "A list of wildcard patterns used to match primitive attributes by name.\n\nSupported syntax of wildcard pattern:\n    `*` - match an arbitrary number of any characters\n    `?` - match any single character\n    `^` - (caret) is used to define a pattern that is to be excluded\n\nExample of wildcard patterns, input: ['xFormOp:translate', 'xformOp:scale','radius']\n    '*' - match any\n    'xformOp:*' - matches 'xFormOp:translate' and 'xformOp:scale'\n    '* ^radius' - match any, but exclude 'radius'\n    '* ^xformOp*' - match any, but exclude 'xFormOp:translate', 'xformOp:scale'", {ogn.MetadataKeys.DEFAULT: '"*"'}, True, "*", False, ''),
        ('inputs:execIn', 'execution', 0, None, 'The input execution (for action graphs only)', {}, True, None, False, ''),
        ('inputs:layerIdentifier', 'token', 0, 'Layer Identifier', 'Identifier of the layer to export to. If empty, it\'ll be exported to the current edit target at the time of usd wirte back.\'\nThis is only used when "Persist To USD" is enabled.', {ogn.MetadataKeys.DEFAULT: '""'}, True, "", False, ''),
        ('inputs:pathPattern', 'string', 0, 'Prim Path Pattern', "A list of wildcard patterns used to match primitives by path.\n\nSupported syntax of wildcard pattern:\n    `*` - match an arbitrary number of any characters\n    `?` - match any single character\n    `^` - (caret) is used to define a pattern that is to be excluded\n\nExample of wildcard patterns, input: ['/Cube0', '/Cube1', '/Box']\n    '*' - match any\n    '* ^/Box' - match any, but exclude '/Box'\n    '* ^/Cube*' - match any, but exclude '/Cube0' and '/Cube1'", {ogn.MetadataKeys.DEFAULT: '"*"'}, True, "*", False, ''),
        ('inputs:prims', 'target', 0, 'Prims', "Target(s) to which the prims in 'primsBundle' will be written to.\nThere is a 1:1 mapping between root prims paths in 'primsBundle' and the Target Prims targets\n*For advanced usage, if 'primsBundle' contains hierarchy, the unique common ancesor paths will have \n the 1:1 mapping to Target Prims targets, with the descendant paths remapped.\n*NOTE* See 'scatterUnderTargets' input for modified exporting behavior\n*WARNING* this can create new prims on the stage.\nIf attributes or prims are removed from 'primsBundle' in subsequent evaluation, they will be removed from targets as well.", {ogn.MetadataKeys.ALLOW_MULTI_INPUTS: '1'}, True, [], False, ''),
        ('inputs:primsBundle', 'bundle', 0, 'Prims Bundle', 'The bundle(s) of multiple prims to be written back.\nThe sourcePrimPath attribute is used to find the destination prim.', {ogn.MetadataKeys.ALLOW_MULTI_INPUTS: '1'}, True, None, False, ''),
        ('inputs:scatterUnderTargets', 'bool', 0, 'Scatter Under Targets', 'If true, the target prims become the parent prims that the bundled prims will be exported *UNDER*. \nIf multiple prims targets are provided, the primsBundle will be duplicated *UNDER* each \ntarget prims.', {ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('inputs:typePattern', 'string', 0, 'Prim Type Pattern', "A list of wildcard patterns used to match primitives by type.\n\nSupported syntax of wildcard pattern:\n    `*` - match an arbitrary number of any characters\n    `?` - match any single character\n    `^` - (caret) is used to define a pattern that is to be excluded\n\nExample of wildcard patterns, input: ['Mesh', 'Cone', 'Cube']\n    '*' - match any\n    '* ^Mesh' - match any, but exclude 'Mesh'\n    '* ^Cone ^Cube' - match any, but exclude 'Cone' and 'Cube'", {ogn.MetadataKeys.DEFAULT: '"*"'}, True, "*", False, ''),
        ('inputs:usdWriteBack', 'bool', 0, 'Persist To USD', 'Whether or not the value should be written back to USD, or kept a Fabric only value', {ogn.MetadataKeys.DEFAULT: 'true'}, True, True, False, ''),
        ('outputs:execOut', 'execution', 0, None, 'The output execution port (for action graphs only)', {}, True, None, False, ''),
        ('state:attrNamesToExport', 'string', 0, None, 'State from previous evaluation', {ogn.MetadataKeys.DEFAULT: '"*"'}, True, "*", False, ''),
        ('state:layerIdentifier', 'token', 0, None, 'State from previous evaluation', {ogn.MetadataKeys.DEFAULT: '""'}, True, "", False, ''),
        ('state:pathPattern', 'string', 0, None, 'State from previous evaluation', {ogn.MetadataKeys.DEFAULT: '"*"'}, True, "*", False, ''),
        ('state:primBundleDirtyId', 'uint64', 0, None, 'State from previous evaluation', {}, True, None, False, ''),
        ('state:scatterUnderTargets', 'bool', 0, None, 'State from previous evaluation', {ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('state:typePattern', 'string', 0, None, 'State from previous evaluation', {ogn.MetadataKeys.DEFAULT: '"*"'}, True, "*", False, ''),
        ('state:usdWriteBack', 'bool', 0, None, 'State from previous evaluation', {ogn.MetadataKeys.DEFAULT: 'true'}, True, True, False, ''),
    ])

    @classmethod
    def _populate_role_data(cls):
        """Populate a role structure with the non-default roles on this node type"""
        role_data = super()._populate_role_data()
        role_data.inputs.attrNamesToExport = og.AttributeRole.TEXT
        role_data.inputs.execIn = og.AttributeRole.EXECUTION
        role_data.inputs.pathPattern = og.AttributeRole.TEXT
        role_data.inputs.prims = og.AttributeRole.TARGET
        role_data.inputs.primsBundle = og.AttributeRole.BUNDLE
        role_data.inputs.typePattern = og.AttributeRole.TEXT
        role_data.outputs.execOut = og.AttributeRole.EXECUTION
        role_data.state.attrNamesToExport = og.AttributeRole.TEXT
        role_data.state.pathPattern = og.AttributeRole.TEXT
        role_data.state.typePattern = og.AttributeRole.TEXT
        return role_data

    class ValuesForInputs(og.DynamicAttributeAccess):
        LOCAL_PROPERTY_NAMES = { }
        """Helper class that creates natural hierarchical access to input attributes"""
        def __init__(self, node: og.Node, attributes, dynamic_attributes: og.DynamicAttributeInterface):
            """Initialize simplified access for the attribute data"""
            context = node.get_graph().get_default_graph_context()
            super().__init__(context, node, attributes, dynamic_attributes)
            self.__bundles = og.BundleContainer(context, node, attributes, [], read_only=True, gpu_ptr_kinds={})
            self._batchedReadAttributes = []
            self._batchedReadValues = []

        @property
        def attrNamesToExport(self):
            data_view = og.AttributeValueHelper(self._attributes.attrNamesToExport)
            return data_view.get()

        @attrNamesToExport.setter
        def attrNamesToExport(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.attrNamesToExport)
            data_view = og.AttributeValueHelper(self._attributes.attrNamesToExport)
            data_view.set(value)
            self.attrNamesToExport_size = data_view.get_array_size()

        @property
        def execIn(self):
            data_view = og.AttributeValueHelper(self._attributes.execIn)
            return data_view.get()

        @execIn.setter
        def execIn(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.execIn)
            data_view = og.AttributeValueHelper(self._attributes.execIn)
            data_view.set(value)

        @property
        def layerIdentifier(self):
            data_view = og.AttributeValueHelper(self._attributes.layerIdentifier)
            return data_view.get()

        @layerIdentifier.setter
        def layerIdentifier(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.layerIdentifier)
            data_view = og.AttributeValueHelper(self._attributes.layerIdentifier)
            data_view.set(value)

        @property
        def pathPattern(self):
            data_view = og.AttributeValueHelper(self._attributes.pathPattern)
            return data_view.get()

        @pathPattern.setter
        def pathPattern(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.pathPattern)
            data_view = og.AttributeValueHelper(self._attributes.pathPattern)
            data_view.set(value)
            self.pathPattern_size = data_view.get_array_size()

        @property
        def prims(self):
            data_view = og.AttributeValueHelper(self._attributes.prims)
            return data_view.get()

        @prims.setter
        def prims(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.prims)
            data_view = og.AttributeValueHelper(self._attributes.prims)
            data_view.set(value)
            self.prims_size = data_view.get_array_size()

        @property
        def primsBundle(self) -> og.BundleContents:
            """Get the bundle wrapper class for the attribute inputs.primsBundle"""
            return self.__bundles.primsBundle

        @property
        def scatterUnderTargets(self):
            data_view = og.AttributeValueHelper(self._attributes.scatterUnderTargets)
            return data_view.get()

        @scatterUnderTargets.setter
        def scatterUnderTargets(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.scatterUnderTargets)
            data_view = og.AttributeValueHelper(self._attributes.scatterUnderTargets)
            data_view.set(value)

        @property
        def typePattern(self):
            data_view = og.AttributeValueHelper(self._attributes.typePattern)
            return data_view.get()

        @typePattern.setter
        def typePattern(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.typePattern)
            data_view = og.AttributeValueHelper(self._attributes.typePattern)
            data_view.set(value)
            self.typePattern_size = data_view.get_array_size()

        @property
        def usdWriteBack(self):
            data_view = og.AttributeValueHelper(self._attributes.usdWriteBack)
            return data_view.get()

        @usdWriteBack.setter
        def usdWriteBack(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.usdWriteBack)
            data_view = og.AttributeValueHelper(self._attributes.usdWriteBack)
            data_view.set(value)

        def _prefetch(self):
            readAttributes = self._batchedReadAttributes
            newValues = _og._prefetch_input_attributes_data(readAttributes)
            if len(readAttributes) == len(newValues):
                self._batchedReadValues = newValues

    class ValuesForOutputs(og.DynamicAttributeAccess):
        LOCAL_PROPERTY_NAMES = { }
        """Helper class that creates natural hierarchical access to output attributes"""
        def __init__(self, node: og.Node, attributes, dynamic_attributes: og.DynamicAttributeInterface):
            """Initialize simplified access for the attribute data"""
            context = node.get_graph().get_default_graph_context()
            super().__init__(context, node, attributes, dynamic_attributes)
            self._batchedWriteValues = { }

        @property
        def execOut(self):
            data_view = og.AttributeValueHelper(self._attributes.execOut)
            return data_view.get()

        @execOut.setter
        def execOut(self, value):
            data_view = og.AttributeValueHelper(self._attributes.execOut)
            data_view.set(value)

        def _commit(self):
            _og._commit_output_attributes_data(self._batchedWriteValues)
            self._batchedWriteValues = { }

    class ValuesForState(og.DynamicAttributeAccess):
        """Helper class that creates natural hierarchical access to state attributes"""
        def __init__(self, node: og.Node, attributes, dynamic_attributes: og.DynamicAttributeInterface):
            """Initialize simplified access for the attribute data"""
            context = node.get_graph().get_default_graph_context()
            super().__init__(context, node, attributes, dynamic_attributes)
            self.attrNamesToExport_size = 1
            self.pathPattern_size = 1
            self.typePattern_size = 1

        @property
        def attrNamesToExport(self):
            data_view = og.AttributeValueHelper(self._attributes.attrNamesToExport)
            self.attrNamesToExport_size = data_view.get_array_size()
            return data_view.get()

        @attrNamesToExport.setter
        def attrNamesToExport(self, value):
            data_view = og.AttributeValueHelper(self._attributes.attrNamesToExport)
            data_view.set(value)
            self.attrNamesToExport_size = data_view.get_array_size()

        @property
        def layerIdentifier(self):
            data_view = og.AttributeValueHelper(self._attributes.layerIdentifier)
            return data_view.get()

        @layerIdentifier.setter
        def layerIdentifier(self, value):
            data_view = og.AttributeValueHelper(self._attributes.layerIdentifier)
            data_view.set(value)

        @property
        def pathPattern(self):
            data_view = og.AttributeValueHelper(self._attributes.pathPattern)
            self.pathPattern_size = data_view.get_array_size()
            return data_view.get()

        @pathPattern.setter
        def pathPattern(self, value):
            data_view = og.AttributeValueHelper(self._attributes.pathPattern)
            data_view.set(value)
            self.pathPattern_size = data_view.get_array_size()

        @property
        def primBundleDirtyId(self):
            data_view = og.AttributeValueHelper(self._attributes.primBundleDirtyId)
            return data_view.get()

        @primBundleDirtyId.setter
        def primBundleDirtyId(self, value):
            data_view = og.AttributeValueHelper(self._attributes.primBundleDirtyId)
            data_view.set(value)

        @property
        def scatterUnderTargets(self):
            data_view = og.AttributeValueHelper(self._attributes.scatterUnderTargets)
            return data_view.get()

        @scatterUnderTargets.setter
        def scatterUnderTargets(self, value):
            data_view = og.AttributeValueHelper(self._attributes.scatterUnderTargets)
            data_view.set(value)

        @property
        def typePattern(self):
            data_view = og.AttributeValueHelper(self._attributes.typePattern)
            self.typePattern_size = data_view.get_array_size()
            return data_view.get()

        @typePattern.setter
        def typePattern(self, value):
            data_view = og.AttributeValueHelper(self._attributes.typePattern)
            data_view.set(value)
            self.typePattern_size = data_view.get_array_size()

        @property
        def usdWriteBack(self):
            data_view = og.AttributeValueHelper(self._attributes.usdWriteBack)
            return data_view.get()

        @usdWriteBack.setter
        def usdWriteBack(self, value):
            data_view = og.AttributeValueHelper(self._attributes.usdWriteBack)
            data_view.set(value)

    def __init__(self, node):
        super().__init__(node)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_INPUT)
        self.inputs = OgnWritePrimsV2Database.ValuesForInputs(node, self.attributes.inputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_OUTPUT)
        self.outputs = OgnWritePrimsV2Database.ValuesForOutputs(node, self.attributes.outputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_STATE)
        self.state = OgnWritePrimsV2Database.ValuesForState(node, self.attributes.state, dynamic_attributes)
