"""Implementation of the node OgnTutorialDynamicAttributesPy.ogn"""
from contextlib import suppress
from operator import xor

import omni.graph.core as og


class OgnTutorialDynamicAttributesPy:
    @staticmethod
    def compute(db) -> bool:
        """Compute the output based on the input and the presence or absence of dynamic attributes"""
        raw_output = db.inputs.value

        # The suppression of the AttributeError will just skip this section of code if the dynamic attribute
        # is not present
        with suppress(AttributeError):
            # firstBit will invert the bit with its number, if present.
            if 0 <= db.inputs.firstBit <= 31:
                raw_output = xor(raw_output, 2**db.inputs.firstBit)
            else:
                db.log_error(f"Could not xor bit {db.inputs.firstBit}. Must be in [0, 31]")

        with suppress(AttributeError):
            # secondBit will invert the bit with its number, if present
            if 0 <= db.inputs.secondBit <= 31:
                raw_output = xor(raw_output, 2**db.inputs.secondBit)
            else:
                db.log_error(f"Could not xor bit {db.inputs.secondBit}. Must be in [0, 31]")

        with suppress(AttributeError):
            # invert will invert the bits, if the role is set and the attribute access is correct
            _ = db.inputs.invert
            if (
                db.role.inputs.invert == og.AttributeRole.TIMECODE
                and db.attributes.inputs.invert == db.abi_node.get_attribute(db.tokens.invert)
            ):
                raw_output = xor(raw_output, 0xFFFFFFFF)

        db.outputs.result = raw_output
