def METHOD_NAME(self, policy):  # type: ignore[no-untyped-def]
    """
    Returns the type of the given policy
    :param string or dict policy: Policy data
    :return PolicyTypes: Type of the given policy. None, if type could not be inferred
    """
    # Must handle intrinsic functions. Policy could be a primitive type or an intrinsic function
    # Managed policies are of type string
    if isinstance(policy, str):
        return PolicyTypes.MANAGED_POLICY
    # Handle the special case for 'if' intrinsic function
    if is_intrinsic_if(policy):
        return self._get_type_from_intrinsic_if(policy)  # type: ignore[no-untyped-call]
    # Intrinsic functions are treated as managed policies by default
    if is_intrinsic(policy):
        return PolicyTypes.MANAGED_POLICY
    # Policy statement is a dictionary with the key "Statement" in it
    if isinstance(policy, dict) and "Statement" in policy:
        return PolicyTypes.POLICY_STATEMENT
    # This could be a policy template then.
    if self._is_policy_template(policy):  # type: ignore[no-untyped-call]
        return PolicyTypes.POLICY_TEMPLATE
    # Nothing matches. Don't take opinions on how to handle it. Instead just set the appropriate type.
    return PolicyTypes.UNKNOWN