from typing import Dict
from typing import Optional
from typing import Any


def get_injection_requests(
    type_hints: Dict[str, type], cname: str, component: Optional[Any] = None
) -> Dict[str, type]:
    """
    Given a dict of type hints, filter it to the requested injection types.

    :param type_hints: The type hints to inspect.
    :param cname: The component name.
    :param component: The component if it has been instantiated.
    """
    requests = {}

    for n, inject_type in type_hints.items():
        # If the variable is private ignore it
        if n.startswith("_"):
            continue

        # If the variable has been set, skip it
        if hasattr(component, n):
            continue

        # Check for generic types from the typing module
        origin = getattr(inject_type, "__origin__", None)
        if origin is not None:
            inject_type = origin

        # If the type is not actually a type, give a meaningful error
        if not isinstance(inject_type, type):
            raise TypeError(
                f"Component {cname} has a non-type annotation {n}: {inject_type}\n"
                "Lone non-injection variable annotations are disallowed, did you want to assign a static variable?"
            )

        requests[n] = inject_type

    return requests