from typing import Union
from typing import List
from typing import Any


def combine_datas(
    data_a: Union[List[Any], Any], data_b: Union[List[Any], Any]
) -> Union[List[Any], Any]:
    # pylint: disable=bad-option-value,isinstance-second-argument-not-valid-type
    """
    Combines data where either may be versioned (a list) or merged (a single element)

    * Return list: a and b are non empty lists, a is empty and b is a list, b is empty and a is a list, both are empty
    * Return single item: both are non lists, a is empty and b is not list, b is empty and a is not list

    Examples:
        * data_a = [], data_b = 'foo' -> 'foo'
        * data_a = 'foo', data_b = 'bar' -> 'bar'
        * data_a = 'foo', data_b = [] -> 'foo'
        * data_a = ['foo'], data_b = ['bar'] -> ['foo', 'bar']
        * data_a = 'foo', data_b = ['bar'] -> Error, both are non empty but one is versioned and the other is merged

    Args:
        data_a: First data to combine
        data_b: Second data to combine

    Returns:
        Data a and b combined
    """
    if data_a and data_b:
        # Assert both are lists or not lists
        assert isinstance(data_a, List) == isinstance(
            data_b, List
        ), f"Cannot combine versioned and non-versioned data: {data_a} + {data_b}"

    if (
        data_a
        and data_b
        and not isinstance(data_a, List)
        and not isinstance(data_b, List)
    ) or (data_b and not data_a and not isinstance(data_b, List)):
        return data_b
    elif data_a and not data_b and not isinstance(data_a, List):
        return data_a
    else:
        return data_a + data_b