"""Houses all of the type definitions for the various interface argument types.

For clarity these types are stored in a structure that gives them a unified naming:

.. code-block:: python

    from omni.graph.core.typing import NodeSpec_t
    def get_node(node_spec: NodeSpec_t):
        pass

The convention used is that X_t is a singular item and Xs_t is a union of the singular item and a list of them.
"""
from typing import Any, Dict, List, Tuple, Union

import omni.graph.core as og
from pxr import Sdf, Usd

# ======================================================================
# Values for type hints on methods that take a variety of convertible types as parameters

Graph_t = Union[str, Sdf.Path, og.Graph]
"""Typing that identifies an existing omni.graph.core.Graph object"""
Graphs_t = Union[Graph_t, List[Graph_t]]
"""Typing that identifies a list of existing omni.graph.core.Graph objects"""
# Added specs for consistency, though for graphs no extra information is currently needed to identify them
GraphSpec_t = Graph_t
"""Typing that identifies an existing omni.graph.core.Graph object"""
GraphSpecs_t = Graphs_t
"""Typing that identifies a list of existing omni.graph.core.Graph objects"""

NewNode_t = Union[str, Sdf.Path, Tuple[str, og.Graph]]
"""Typing for information required to create a new node"""

Node_t = Union[str, og.Node, Sdf.Path, Usd.Prim, Usd.Typed]
"""Typing that identifies an existing omni.graph.core.Node object"""
Nodes_t = Union[Node_t, List[Node_t]]
"""Typing that identifies a list of existing omni.graph.core.Node objects"""

NodeSpec_t = Union[Node_t, Tuple[str, GraphSpec_t]]
"""Typing that identifies an existing omni.graph.core.Node object, with optional graph for disambiguation"""
NodeSpecs_t = Union[NodeSpec_t, List[NodeSpec_t]]
"""Typing that identifies a list of existing omni.graph.core.Node objects, with optional graph for disambiguation"""

NodeType_t = Union[str, og.NodeType, og.Node, Usd.Prim, Usd.Typed]
"""Typing that identifies an existing omni.graph.core.NodeType object"""
NodeTypes_t = Union[NodeType_t, List[NodeType_t]]
"""Typing that identifies a list of existing omni.graph.core.NodeType objects"""

Attribute_t = Union[str, Sdf.Path, og.Attribute, Usd.Attribute]
"""Typing that identifies an existing omni.graph.core.Attribute object"""
Attributes_t = Union[Attribute_t, List[Attribute_t]]
"""Typing that identifies a list of existing omni.graph.core.Attribute objects"""

AttributeWithValue_t = Union[Attribute_t, og.AttributeData]
"""Typing for an attribute-like object that references a value in FlatCache"""
AttributesWithValues_t = Union[AttributeWithValue_t, List[AttributeWithValue_t]]
"""Typing for a list of attribute-like objects that reference values in FlatCache"""

AttributeType_t = Union[str, og.Type]
"""Typing that identifies an existing omni.graph.core.Type definition"""

ExtendedAttribute_t = Union[og.AttributePortType, Tuple[og.AttributePortType, Union[str, List[str]]]]
"""Typing for an extended attribute type description"""

Path_t = Union[str, Sdf.Path]
"""Typing for a path in the USD stage"""

Prim_t = Union[str, Sdf.Path, og.Node, Usd.Prim, Usd.Typed]
"""Typing for an existing USD prim"""
Prims_t = Union[Prim_t, List[Prim_t]]
"""Typing for a list of existing USD prims"""

PrimAttrs_t = Dict[str, Tuple[Union[str, og.Type], Any]]
"""Typing for a description of attribute values for a prim - a dictionary of name:(type,value)"""

CreatePrim_t = Tuple[Path_t, PrimAttrs_t]
"""Typing for information required to create a prim with a predefined set of values"""
CreatePrimst_t = Union[CreatePrim_t, List[CreatePrim_t]]
"""Typing for information required to create a list of prims with a predefined set of values"""

# An attribute that is either unique by itself or which has optional node and graph parts to help look it up.
# This would be passed in as arguments to a function that needs to uniquely identify an existing attribute.
# It differs from a regular attribute in allowing a relative path to the attribute within the node/graph
AttributeSpec_t = Union[og.Attribute, str, Sdf.Path, Tuple[str, Node_t], Tuple[str, Node_t, Graph_t]]
"""Typing for information required to identify an existing og.Attribute"""
AttributeSpecs_t = Union[AttributeSpec_t, List[AttributeSpec_t]]
"""Typing for information required to identify a list of existing og.Attributes"""

VariableName_t = str
"""Typing information required to specify a variable name"""
VariableType_t = Union[str, og.Type]
"""Typing information required to specify a variable type"""
Variable_t = Union[og.IVariable, Tuple[GraphSpec_t, VariableName_t]]
"""Typing information required to specify a variable"""
Variables_t = Union[Variable_t, List[Variable_t]]
"""Typing information required to specify a list of variable"""
