def match_kv(condition):
    """Take a list of key value pairs and generate an EQL expression.

    :param dict condition: The source text query
    :rtype: ast.Expression
    """
    from . import ast
    from .parser import parse_field
    if not isinstance(condition, dict):
        raise TypeError('unsupported type {} to match_kv. Expected {}'.
            format(type(condition), ast.EqlNode))
    and_node = ast.Boolean(True)
    for field_text, field_match in sorted(condition.items()):
        if not isinstance(field_match, (list, tuple)):
            field_match = [field_match]
        field_node = parse_field(field_text)
        exact = []
        wildcards = []
        for term in field_match:
            literal = ast.Literal.from_python(term)
            if isinstance(literal, ast.String) and '*' in literal.value:
                wildcards.append(literal)
            else:
                exact.append(literal)
        match_node = ast.InSet(field_node, exact).optimize()
        if wildcards:
            match_node |= ast.FunctionCall('wildcard', [field_node] + wildcards
                )
        and_node &= match_node
    return and_node
