from triton import AST_NODE
from typing import TypeVar, Union, Tuple, List, Generator, Dict, Optional, Iterable, Any, Iterator
from enum import IntEnum

# Utils types
BitSize = int
"""Integer representing a size in bits"""

ByteSize = int
"""Integer representing a size in bytes"""

Addr = int
"""Integer representing an address"""

# Triton Types
AstNode = TypeVar("AstNode")
"""`AstNode <https://triton.quarkslab.com/documentation/doxygen/py_AstNode_page.html>`_ SMT logic formula as returned by Triton"""

AstType = IntEnum("AstType", {k: v for k, v in AST_NODE.__dict__.items() if isinstance(v, int)})
"""Enum of all AstNode possible types as defined by the `AST_NODE <https://triton.quarkslab.com/documentation/doxygen/py_AST_NODE_page.html>`_ object of Triton"""

Register = TypeVar("Register")
""""`Register <https://triton.quarkslab.com/documentation/doxygen/py_Register_page.html>`_ object as returned by Triton"""

SymbolicExpression = TypeVar("SymbolicExpression")
"""`SymbolicExpression <https://triton.quarkslab.com/documentation/doxygen/py_SymbolicExpression_page.html>`_ object as used by Triton"""

SymbolicVariable = TypeVar("SymbolicVariable")
"""`SymbolicVariable <https://triton.quarkslab.com/documentation/doxygen/py_SymbolicVariable_page.html>`_ object as generated by Triton"""

# TritonAst & Grammar Types
Expr = AstNode
"""Alias for :py:obj:`AstNode`, to abstract to Triton type"""

SymVarMap = Dict[str, SymbolicVariable]
"""Dictionnary of symbolic variables names to theirs Triton object instance"""


# Synthesis types
Hash = bytes
"""Hash abstract type used to performed lookup in tables. As now the only hash
type supported is MD5 the underlying value is bytes."""

Char = str
"""String of size one. Used to represent normalized variables names"""

Input = Dict[Char, int]
"""An Input is a valuation of all inputs variables of an expression"""

Output = int
"""Value resulting of evaluating an Input on a given expression"""

IOPair = Tuple[Input, Output]
"""Represent a given input valuation and the resulting output integer"""

IOVector = List[IOPair]
"""List of input-outputs pairs"""
