from typing import Tuple
from typing import Callable
import hashlib
from typing import Union


def _hash(
    tpl: Tuple, hash_function: Callable = hashlib.sha1, as_int: bool = True
) -> Union[str, int]:
    """Deterministic hash function. The main use here is
    providing a `commit_hash` for a Dataset to compare across
    saves/loads and ensure that operations are re-run if the hash
    ever changes

    Args:
        tpl (Tuple): Tuple of data to hash
        hash_function (Callable, hashlib.sha1): Hash function from
            python hashlib. Defaults to sha1 (same as git)
        as_int (bool, optional): Encode hash as int

    Returns:
        Union[str, int]: Deterministic hash using tpl data
    """
    m = hash_function()
    for e in tpl:
        if isinstance(e, str):
            e_bytes = e.encode("utf-8")
        else:
            e_bytes = bytes(e)
        m.update(e_bytes)

    hd = m.hexdigest()

    if as_int:
        return int(hd, 16)
    else:
        return hd