def wrap_query(query, props):
    """
    Surrounds the core Elasticsearch aggregation <query> with one
    Terms aggregation for every field in the list <props>.

    Fields at the beginning of the list will end up as outer aggregations,
    while later fields will be nested more deeply and the core query will
    be nested deepest.

    :param query: A `dict` representing an Elasticsearch aggregation.
    :param props: A list of Elasticsearch text field names.
    :returns: Aggregation containing <query> wrapped in Terms aggregations.
    """

    if len(props) == 0:
        return query

    field_name = props[-1]
    field_full = 'properties.{}.raw'.format(field_name)

    remaining_fields = props[:-1]

    wrapped = {
        'distinct_{}'.format(field_name): {
            'terms': {
                'size': 10000,
                'field': field_full,
                'order': {'_key': 'asc'}
            },
            'aggregations': query
        }
    }

    return wrap_query(wrapped, remaining_fields)