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

Exports data from an input bundle into a USD prim
"""

import carb
import numpy

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 OgnExportUSDPrimDatabase(og.Database):
    """Helper class providing simplified access to data on nodes of type omni.graph.ExportUSDPrim

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.applyTransform
            inputs.attrNamesToExport
            inputs.bundle
            inputs.excludedAttrNames
            inputs.exportToRootLayer
            inputs.inputAttrNames
            inputs.layerName
            inputs.onlyExportToExisting
            inputs.outputAttrNames
            inputs.primPathFromBundle
            inputs.removeMissingAttrs
            inputs.renameAttributes
            inputs.timeVaryingAttributes
            inputs.usdTimecode
        Outputs:
            outputs.prim
        State:
            state.prevApplyTransform
            state.prevAttrNamesToExport
            state.prevBundleDirtyID
            state.prevExcludedAttrNames
            state.prevExportToRootLayer
            state.prevInputAttrNames
            state.prevLayerName
            state.prevOnlyExportToExisting
            state.prevOutputAttrNames
            state.prevPrimDirtyIDs
            state.prevPrimPathFromBundle
            state.prevRemoveMissingAttrs
            state.prevRenameAttributes
            state.prevTimeVaryingAttributes
            state.prevUsdTimecode

    Predefined Tokens:
        tokens.primPath
        tokens.primType
        tokens.primTime
        tokens.primCount
        tokens.transform
    """

    # 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:applyTransform', 'bool', 0, None, 'If true, apply the transform necessary to transform any transforming attributes from the space of the node into the space of the specified prim.', {'displayGroup': 'parameters', ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('inputs:attrNamesToExport', 'token', 0, 'Attributes To Export', 'Comma or space separated text, listing the names of attributes in the input data to be exported \nor empty to import all attributes.', {'displayGroup': 'parameters', ogn.MetadataKeys.DEFAULT: '""'}, True, "", False, ''),
        ('inputs:bundle', 'bundle', 0, None, 'The bundle from which data should be exported.', {}, True, None, False, ''),
        ('inputs:excludedAttrNames', 'token', 0, 'Attributes To Exclude', 'Attributes to be excluded from being exported', {ogn.MetadataKeys.DEFAULT: '""'}, True, "", False, ''),
        ('inputs:exportToRootLayer', 'bool', 0, 'Export to Root Layer', 'If true, prims are exported in the root layer, otherwise the layer specified by "layerName" is used.', {ogn.MetadataKeys.DEFAULT: 'true'}, True, True, False, ''),
        ('inputs:inputAttrNames', 'token', 0, 'Attributes To Rename', 'Comma or space separated text, listing the names of attributes in the input data to be renamed', {ogn.MetadataKeys.DEFAULT: '""'}, True, "", False, ''),
        ('inputs:layerName', 'token', 0, 'Layer Name', 'Identifier of the layer to export to if "exportToRootLayer" is false, or leave this blank to export to the session layer', {ogn.MetadataKeys.DEFAULT: '""'}, True, "", False, ''),
        ('inputs:onlyExportToExisting', 'bool', 0, None, 'If true, only attributes that already exist in the specified output prim will have data transferred to them from the input bundle.', {'displayGroup': 'parameters', ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('inputs:outputAttrNames', 'token', 0, 'New Attribute Names', 'Comma or space separated text, listing the new names for the attributes listed in inputAttrNames', {ogn.MetadataKeys.DEFAULT: '""'}, True, "", False, ''),
        ('inputs:primPathFromBundle', 'bool', 0, None, 'When true, if there is a "primPath" token attribute inside the bundle, that will be the path of the USD prim to write to, \nelse the "outputs:prim" attribute below will be used for the USD prim path.', {'displayGroup': 'parameters', ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('inputs:removeMissingAttrs', 'bool', 0, 'Export to Root Layer', "If true, any attributes on the USD prim(s) being written to, that aren't in the input data, \nwill be removed from the USD prim(s).", {ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('inputs:renameAttributes', 'bool', 0, None, 'If true, attributes listed in "inputAttrNames" will be exported to attributes with the names specified in "outputAttrNames". \nNote: to avoid potential issues with redundant attributes being created while typing, keep this off until after \nspecifying all input and output attribute names.', {'displayGroup': 'parameters', ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('inputs:timeVaryingAttributes', 'bool', 0, None, 'Check whether the USD attributes should be time-varying and if so, export their data to a time sample at the time "usdTimecode".', {'displayGroup': 'parameters', ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('inputs:usdTimecode', 'double', 0, None, 'The time at which to evaluate the transform of the USD prim for applyTransform.', {'displayGroup': 'parameters', ogn.MetadataKeys.DEFAULT: '0'}, True, 0, False, ''),
        ('outputs:prim', 'bundle', 0, None, 'The USD prim(s) to which data should be exported if primPathFromBundle is false or if the bundle doesn\'t have a "primPath" token attribute.  \nNote: this is really an input, since the node just receives the path to the prim.  The node does not contain the prim.', {ogn.MetadataKeys.HIDDEN: 'true'}, False, None, False, ''),
        ('state:prevApplyTransform', 'bool', 0, None, 'Value of "applyTransform" input from previous run', {}, True, None, False, ''),
        ('state:prevAttrNamesToExport', 'token', 0, None, 'Value of "attrNamesToExport" input from previous run', {}, True, None, False, ''),
        ('state:prevBundleDirtyID', 'uint64', 0, None, 'Dirty ID of input bundle from previous run', {}, True, None, False, ''),
        ('state:prevExcludedAttrNames', 'token', 0, None, 'Value of "excludedAttrNames" input from previous run', {}, True, None, False, ''),
        ('state:prevExportToRootLayer', 'bool', 0, None, 'Value of "exportToRootLayer" input from previous run', {}, True, None, False, ''),
        ('state:prevInputAttrNames', 'token', 0, None, 'Value of "inputAttrNames" input from previous run', {}, True, None, False, ''),
        ('state:prevLayerName', 'token', 0, None, 'Value of "layerName" input from previous run', {}, True, None, False, ''),
        ('state:prevOnlyExportToExisting', 'bool', 0, None, 'Value of "onlyExportToExisting" input from previous run', {}, True, None, False, ''),
        ('state:prevOutputAttrNames', 'token', 0, None, 'Value of "outputAttrNames" input from previous run', {}, True, None, False, ''),
        ('state:prevPrimDirtyIDs', 'uint64[]', 0, None, 'Dirty IDs of input prims from previous run', {}, True, None, False, ''),
        ('state:prevPrimPathFromBundle', 'bool', 0, None, 'Value of "primPathFromBundle" input from previous run', {}, True, None, False, ''),
        ('state:prevRemoveMissingAttrs', 'bool', 0, None, 'Value of "removeMissingAttrs" input from previous run', {}, True, None, False, ''),
        ('state:prevRenameAttributes', 'bool', 0, None, 'Value of "renameAttributes" input from previous run', {}, True, None, False, ''),
        ('state:prevTimeVaryingAttributes', 'bool', 0, None, 'Value of "timeVaryingAttributes" input from previous run', {}, True, None, False, ''),
        ('state:prevUsdTimecode', 'double', 0, None, 'Value of "usdTimecode" input from previous run', {}, True, None, False, ''),
    ])

    class tokens:
        primPath = "primPath"
        primType = "primType"
        primTime = "primTime"
        primCount = "primCount"
        transform = "transform"

    @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.bundle = og.AttributeRole.BUNDLE
        role_data.outputs.prim = og.AttributeRole.BUNDLE
        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 applyTransform(self):
            data_view = og.AttributeValueHelper(self._attributes.applyTransform)
            return data_view.get()

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

        @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)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        @usdTimecode.setter
        def usdTimecode(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.usdTimecode)
            data_view = og.AttributeValueHelper(self._attributes.usdTimecode)
            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.__bundles = og.BundleContainer(context, node, attributes, [], read_only=False, gpu_ptr_kinds={})
            self._batchedWriteValues = { }

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

        @prim.setter
        def prim(self, bundle: og.BundleContents):
            """Overwrite the bundle attribute outputs.prim with a new bundle"""
            if not isinstance(bundle, og.BundleContents):
                carb.log_error("Only bundle attributes can be assigned to another bundle attribute")
            self.__bundles.prim.bundle = bundle

        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.prevPrimDirtyIDs_size = None

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        @prevUsdTimecode.setter
        def prevUsdTimecode(self, value):
            data_view = og.AttributeValueHelper(self._attributes.prevUsdTimecode)
            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 = OgnExportUSDPrimDatabase.ValuesForInputs(node, self.attributes.inputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_OUTPUT)
        self.outputs = OgnExportUSDPrimDatabase.ValuesForOutputs(node, self.attributes.outputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_STATE)
        self.state = OgnExportUSDPrimDatabase.ValuesForState(node, self.attributes.state, dynamic_attributes)
