from typing import Any
from typing import List


def validate_entry_context(entry_context: Any, keys: List[str], unpack_nested_elements: bool):
    """ Validate entry context structure is valid, should be:
        - For unpack_nested_elements==False:
            1. List[Dict[str, str/bool/int/float]]
            2. List[str/bool/int/float]
            3. Dict[str, str/bool/int/float] - for developer it will be in first index of a list.
        - For unpack_nested_elements==True:
            1. Dict[str, Any]

    Args:
        entry_context: Entry context to validate
        keys: keys to collect data from
        unpack_nested_elements: True for unpacking nested elements, False otherwise.

    Raises:
        ValueError: If structure is not valid.
        data_type (str): The type of information in the context path.
    """
    exception_msg = "When unpack_nested_elements argument is set to True, the context object for the path should be " \
                    "of type dict"
    if unpack_nested_elements:
        if not isinstance(entry_context, dict):
            raise ValueError(exception_msg)
        else:
            return

    exception_msg = "The context object for the specified path should be of one of the following types:" \
                    " dict[str,str] or list[dict[str,str]] or List[str/bool/int/float]"
    if not isinstance(entry_context, (list, dict)):
        raise ValueError(exception_msg)

    data_type = 'dicts'

    if isinstance(entry_context, dict):
        return data_type

    has_seen_dict = False
    for item in entry_context:
        if not isinstance(item, dict):
            if not has_seen_dict:
                break
            else:
                raise ValueError(exception_msg)

        has_seen_dict = True
        for key, value in item.items():
            if key in keys:
                if not isinstance(value, (str, int, float, bool)):
                    raise ValueError(exception_msg)

    if not has_seen_dict:
        data_type = 'list'
        for item in entry_context:
            if not isinstance(item, (str, int, float, bool)):
                raise ValueError(exception_msg)

    return data_type