from typing import List
from typing import Dict


def name_to_index_mapping(category: List[dict]) -> Dict[str, int]:
    """
    Build a mapping from name to index to look up index in O(1) time.
    :param category: The nuImages category table.
    :return: The mapping from category name to category index.
    """
    # The 0 index is reserved for non-labelled background; thus, the categories should start from index 1.
    # Also, sort the categories before looping so that the order is always the same (alphabetical).
    name_to_index = dict()
    i = 1
    sorted_category: List = sorted(category.copy(), key=lambda k: k['name'])
    for c in sorted_category:
        # Ignore the vehicle.ego and flat.driveable_surface classes first; they will be mapped later.
        if c['name'] != 'vehicle.ego' and c['name'] != 'flat.driveable_surface':
            name_to_index[c['name']] = i
            i += 1

    assert max(name_to_index.values()) < 24, \
        'Error: There are {} classes (excluding vehicle.ego and flat.driveable_surface), ' \
        'but there should be 23. Please check your category.json'.format(max(name_to_index.values()))

    # Now map the vehicle.ego and flat.driveable_surface classes.
    name_to_index['flat.driveable_surface'] = 24
    name_to_index['vehicle.ego'] = 31

    # Ensure that each class name is uniquely paired with a class index, and vice versa.
    assert len(name_to_index) == len(set(name_to_index.values())), \
        'Error: There are {} class names but {} class indices'.format(len(name_to_index),
                                                                      len(set(name_to_index.values())))

    return name_to_index