# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#

import omni.graph.core as og

from . import UINodeCommon


class OgnWriteWidgetProperty:
    @staticmethod
    def compute(db) -> bool:
        if db.inputs.write != og.ExecutionAttributeState.DISABLED:
            widget_path = db.inputs.widgetPath
            if not widget_path:
                widget_identifier = db.inputs.widgetIdentifier
                if not widget_identifier:
                    db.log_warning("No widgetIdentifier or widgetPath provided.")
                    return False

                widget = UINodeCommon.get_registered_widget(db.abi_context, widget_identifier)
                if not widget:
                    db.log_warning(f"No widget with identifier '{widget_identifier}' found in this graph.")
                    return False
            else:
                widget = UINodeCommon.find_widget_among_all_windows(widget_path)
                if not widget:
                    db.log_warning(f"No widget found at path '{widget_path}'.")
                    return False
                # For error messages only.
                widget_identifier = widget_path

            property_name = db.inputs.propertyName
            if not property_name:
                db.log_error("No property provided.")
                return False

            if not hasattr(widget, property_name):
                db.log_error(f"Widget '{widget_identifier}' has no property '{property_name}'.")
                return False

            widget_summary = f"widget '{widget_identifier}' ({type(widget)})"
            callbacks = UINodeCommon.get_widget_callbacks(widget)
            if not callbacks:
                db.log_error(f"{widget_summary} is not supported by the WriteWidgetProperty node.")
                return False
            if not hasattr(callbacks, "get_property_names") or not callable(callbacks.get_property_names):
                db.log_error(f"No 'get_property_names' callback found for {widget_summary}")
                return False
            writeable_props = callbacks.get_property_names(widget, True)
            if not writeable_props or property_name not in writeable_props:
                db.log_error(f"'{property_name}' is not a writeable property of {widget_summary}")
                return False
            if not hasattr(callbacks, "set_property_value") or not callable(callbacks.set_property_value):
                db.log_error(f"No 'set_property_value' callback found for {widget_summary}")
                return False
            if not callbacks.set_property_value(widget, property_name, db.inputs.value):
                db.log_error(f"Could not set value of '{property_name}' on {widget_summary}")
                return False
            db.outputs.written = og.ExecutionAttributeState.ENABLED
            return True

        db.log_warning("Unexpected execution with no execution input enabled")
        return False
