"""
Implementation of the Python node accessing attributes through the bundle in which they are contained.
"""
import omni.graph.core as og

# Types recognized by the integer filter
_INTEGER_TYPES = [og.BaseDataType.INT, og.BaseDataType.UINT, og.BaseDataType.INT64, og.BaseDataType.UINT64]


class OgnTutorialBundlesPy:
    """Exercise the bundled data types through a Python OmniGraph node"""

    @staticmethod
    def compute(db) -> bool:
        """Implements the same algorithm as the C++ node OgnTutorialBundles.cpp"""

        full_bundle = db.inputs.fullBundle
        filtered_bundle = db.inputs.filteredBundle
        filters = db.inputs.filters
        output_bundle = db.outputs.combinedBundle

        # This does a copy of the full bundle contents from the input bundle to the output bundle
        output_bundle.bundle = full_bundle

        # Extract the filter flags from the contents of the filters array
        filter_big_arrays = "big" in filters
        filter_type_int = "int" in filters
        filter_name_x = "x" in filters

        # The "attributes" member is a list that can be iterated. The members of the list do not contain real
        # og.Attribute objects, which must always exist, they are wrappers on og.AttributeData objects, which can
        # come and go at runtime.
        for bundled_attribute in filtered_bundle.attributes:

            # The two main accessors for the bundled attribute provide the name and type information
            name = bundled_attribute.name
            attribute_type = bundled_attribute.type

            # Check each of the filters to see which attributes are to be skipped
            if filter_type_int and attribute_type.base_type in _INTEGER_TYPES:
                continue

            if filter_name_x and name.find("x") >= 0:
                continue

            # A method on the bundled attribute provides access to array size (non-arrays are size 1)
            if filter_big_arrays and bundled_attribute.size > 10:
                continue

            # All filters have been passed so the attribute is eligible to be copied onto the output.
            output_bundle.insert(bundled_attribute)

        return True
