from typing import Mapping
from typing import Tuple
from typing import Optional
from typing import Sequence


def _get_sorted_experiment_kinds(
    experiment_kinds: Mapping[str, Tuple[str]],
    distance_kinds_order: Optional[Sequence[str]],
) -> Mapping[str, Tuple[str]]:
    """Sorts experiment_kinds` in order of `distance_kinds_order`, if specified.

    Args:
        experiment_kinds: Different subsets of data to tabulate, e.g. visitation distributions.
        distance_kinds_order: The order in which to run and present the distance algorithms,
            which are keys of `experiment_kinds`.

    Returns:
        `experiment_kinds` sorted according to `distance_kinds_order`.
    """
    if not experiment_kinds:
        raise ValueError("Empty `experiment_kinds`.")

    if distance_kinds_order:
        if len(distance_kinds_order) != len(experiment_kinds):
            raise ValueError(
                f"Order '{distance_kinds_order}' is different length"
                f" to keys '{experiment_kinds.keys()}'."
            )

        if set(distance_kinds_order) != set(experiment_kinds.keys()):
            raise ValueError(
                f"Order '{distance_kinds_order}' is different set"
                f" to keys '{experiment_kinds.keys()}'."
            )

        experiment_kinds = {k: experiment_kinds[k] for k in distance_kinds_order}

    return experiment_kinds