from typing import Dict
from typing import Callable


def create_factory(possibilities_dict: Dict[str, Callable], are_methods: bool = False) -> Callable:
    """
    A generic method for creating factories for the entire project.

    Args:
        possibilities_dict(Dict[str, Callable]): The dictionary which maps object types (as strings!) and returns the
            relevant class constructors.
        are_methods(bool): A flag, true if the factory output are methods, rather than objects. Defaults to False

    Returns:
         The factory function for the given classes/methods mapping.

    """
    def factory_func(requested_object_type: str):  # Inner function!
        if requested_object_type not in possibilities_dict:
            raise ValueError("Object type {0} is NOT supported".format(requested_object_type))
        else:
            if are_methods:
                return possibilities_dict[requested_object_type]
            else:
                return possibilities_dict[requested_object_type]()

    return factory_func