from typing import Any

def contains_any(value, reference):
    if value is None or reference is None: return False
    if isinstance(value, list):
        for item in value:
            if item in reference:
                return True
        return False
    else:
        return value in reference


def contains_all(value, reference):
    if value is None or reference is None: return False
    if isinstance(value, list):
        for item in value:
            if item not in reference:
                return False
        return True

    if isinstance(reference, list):
        if value is None or reference is None: return False
        for item in reference:
            if value not in item:
                return False
        return True

    return value in reference


def contains_only(value, reference):
    if value is None or reference is None: return False
    if isinstance(value, list) and isinstance(reference, list):
        if len(value) != len(reference):
            return False
        for ref in reference:
            if ref not in value:
                return False
    else:
        return value.lower() == str(reference).lower()
    return True
  
def __is_same_type(variable: Any, value: Any) -> bool:
    return (
        isinstance(variable, type(value))
        # ruamel yaml uses subclasses of str as values in some situations to keep
        # quote styles unchanged. In this situation, comparision of type will not work
        # we need to use issubclass to cover this scenario.
        or issubclass(type(value), type(variable))
        or issubclass(type(variable), type(value))
    )

OPERATIONS = {
    "==": lambda value, variable: variable == value,
    "!=": lambda value, variable: variable != value,
    ">": lambda value, variable: variable > value if __is_same_type(variable, value) else False,
    ">=": lambda value, variable: variable >= value if __is_same_type(variable, value) else False,
    "<": lambda value, variable: variable < value if __is_same_type(variable, value) else False,
    "<=": lambda value, variable: variable <= value if __is_same_type(variable, value) else False,
    "containsAny": contains_any,
    "containsAll": contains_all,
    "containsOnly": contains_only,
    "notContainsAny": lambda value, variable: not contains_any(value, variable),
    "notContainsAll": lambda value, variable: not contains_all(value, variable),
}
