# Path: elastalert/util.py
# def add_raw_postfix(field, is_five_or_above):
#     if is_five_or_above:
#         end = '.keyword'
#     else:
#         end = '.raw'
#     if not field.endswith(end):
#         field += end
#     return field
# 
# Path: elastalert/util.py
# def format_index(index, start, end, add_extra=False):
#     """ Takes an index, specified using strftime format, start and end time timestamps,
#     and outputs a wildcard based index string to match all possible timestamps. """
#     # Convert to UTC
#     start -= start.utcoffset()
#     end -= end.utcoffset()
#     original_start = start
#     indices = set()
#     while start.date() <= end.date():
#         indices.add(start.strftime(index))
#         start += datetime.timedelta(days=1)
#     num = len(indices)
#     if add_extra:
#         while len(indices) == num:
#             original_start -= datetime.timedelta(days=1)
#             new_index = original_start.strftime(index)
#             assert new_index != index, "You cannot use a static index with search_extra_index"
#             indices.add(new_index)
# 
#     return ','.join(indices)
# 
# Path: elastalert/util.py
# def lookup_es_key(lookup_dict, term):
#     """ Performs iterative dictionary search for the given term.
#     :returns: The value identified by term or None if it cannot be found.
#     """
#     value_dict, value_key = _find_es_dict_by_key(lookup_dict, term)
#     return None if value_key is None else value_dict[value_key]
# 
# Path: elastalert/util.py
# def parse_deadline(value):
#     """Convert ``unit=num`` spec into a ``datetime`` object."""
#     duration = parse_duration(value)
#     return ts_now() + duration
# 
# Path: elastalert/util.py
# def parse_duration(value):
#     """Convert ``unit=num`` spec into a ``timedelta`` object."""
#     unit, num = value.split('=')
#     return datetime.timedelta(**{unit: int(num)})
# 
# Path: elastalert/util.py
# def replace_dots_in_field_names(document):
#     """ This method destructively modifies document by replacing any dots in
#     field names with an underscore. """
#     for key, value in list(document.items()):
#         if isinstance(value, dict):
#             value = replace_dots_in_field_names(value)
#         if isinstance(key, string_types) and key.find('.') != -1:
#             del document[key]
#             document[key.replace('.', '_')] = value
#     return document
# 
# Path: elastalert/util.py
# def resolve_string(string, match, missing_text='<MISSING VALUE>'):
#     """
#         Given a python string that may contain references to fields on the match dictionary,
#             the strings are replaced using the corresponding values.
#         However, if the referenced field is not found on the dictionary,
#             it is replaced by a default string.
#         Strings can be formatted using the old-style format ('%(field)s') or
#             the new-style format ('{match[field]}').
# 
#         :param string: A string that may contain references to values of the 'match' dictionary.
#         :param match: A dictionary with the values to replace where referenced by keys in the string.
#         :param missing_text: The default text to replace a formatter with if the field doesnt exist.
#     """
#     flat_match = flatten_dict(match)
#     flat_match.update(match)
#     dd_match = collections.defaultdict(lambda: missing_text, flat_match)
#     dd_match['_missing_value'] = missing_text
#     while True:
#         try:
#             string = string % dd_match
#             string = string.format(**dd_match)
#             break
#         except KeyError as e:
#             if '{%s}' % str(e).strip("'") not in string:
#                 break
#             string = string.replace('{%s}' % str(e).strip("'"), '{_missing_value}')
# 
#     return string
# 
# Path: elastalert/util.py
# def set_es_key(lookup_dict, term, value):
#     """ Looks up the location that the term maps to and sets it to the given value.
#     :returns: True if the value was set successfully, False otherwise.
#     """
#     value_dict, value_key = _find_es_dict_by_key(lookup_dict, term)
# 
#     if value_dict is not None:
#         value_dict[value_key] = value
#         return True
# 
#     return False
# 
# Path: elastalert/util.py
# def should_scrolling_continue(rule_conf):
#     """
#     Tells about a rule config if it can scroll still or should stop the scrolling.
# 
#     :param: rule_conf as dict
#     :rtype: bool
#     """
#     max_scrolling = rule_conf.get('max_scrolling_count')
#     stop_the_scroll = 0 < max_scrolling <= rule_conf.get('scrolling_cycle')
# 
#     return not stop_the_scroll


from datetime import datetime
from datetime import timedelta
from dateutil.parser import parse as dt
from elastalert.util import add_raw_postfix
from elastalert.util import format_index
from elastalert.util import lookup_es_key
from elastalert.util import parse_deadline
from elastalert.util import parse_duration
from elastalert.util import replace_dots_in_field_names
from elastalert.util import resolve_string
from elastalert.util import set_es_key
from elastalert.util import should_scrolling_continue
import mock
import pytest
def test_replace_dots_in_field_names(ea):
    actual = {
        'a': {
            'b.c': 'd',
            'e': {
                'f': {
                    'g.h': 0
                }
            }
        },
        'i.j.k': 1,
        'l': {
            'm': 2
        }
    }
    expected = {
        'a': {
            'b_c': 'd',
            'e': {
                'f': {
                    'g_h': 0
                }
            }
        },
        'i_j_k': 1,
        'l': {
            'm': 2
        }
    }
    assert replace_dots_in_field_names(actual) == expected

# Path: elastalert/util.py
# def add_raw_postfix(field, is_five_or_above):
#     if is_five_or_above:
#         end = '.keyword'
#     else:
#         end = '.raw'
#     if not field.endswith(end):
#         field += end
#     return field
# 
# Path: elastalert/util.py
# def format_index(index, start, end, add_extra=False):
#     """ Takes an index, specified using strftime format, start and end time timestamps,
#     and outputs a wildcard based index string to match all possible timestamps. """
#     # Convert to UTC
#     start -= start.utcoffset()
#     end -= end.utcoffset()
#     original_start = start
#     indices = set()
#     while start.date() <= end.date():
#         indices.add(start.strftime(index))
#         start += datetime.timedelta(days=1)
#     num = len(indices)
#     if add_extra:
#         while len(indices) == num:
#             original_start -= datetime.timedelta(days=1)
#             new_index = original_start.strftime(index)
#             assert new_index != index, "You cannot use a static index with search_extra_index"
#             indices.add(new_index)
# 
#     return ','.join(indices)
# 
# Path: elastalert/util.py
# def lookup_es_key(lookup_dict, term):
#     """ Performs iterative dictionary search for the given term.
#     :returns: The value identified by term or None if it cannot be found.
#     """
#     value_dict, value_key = _find_es_dict_by_key(lookup_dict, term)
#     return None if value_key is None else value_dict[value_key]
# 
# Path: elastalert/util.py
# def parse_deadline(value):
#     """Convert ``unit=num`` spec into a ``datetime`` object."""
#     duration = parse_duration(value)
#     return ts_now() + duration
# 
# Path: elastalert/util.py
# def parse_duration(value):
#     """Convert ``unit=num`` spec into a ``timedelta`` object."""
#     unit, num = value.split('=')
#     return datetime.timedelta(**{unit: int(num)})
# 
# Path: elastalert/util.py
# def replace_dots_in_field_names(document):
#     """ This method destructively modifies document by replacing any dots in
#     field names with an underscore. """
#     for key, value in list(document.items()):
#         if isinstance(value, dict):
#             value = replace_dots_in_field_names(value)
#         if isinstance(key, string_types) and key.find('.') != -1:
#             del document[key]
#             document[key.replace('.', '_')] = value
#     return document
# 
# Path: elastalert/util.py
# def resolve_string(string, match, missing_text='<MISSING VALUE>'):
#     """
#         Given a python string that may contain references to fields on the match dictionary,
#             the strings are replaced using the corresponding values.
#         However, if the referenced field is not found on the dictionary,
#             it is replaced by a default string.
#         Strings can be formatted using the old-style format ('%(field)s') or
#             the new-style format ('{match[field]}').
# 
#         :param string: A string that may contain references to values of the 'match' dictionary.
#         :param match: A dictionary with the values to replace where referenced by keys in the string.
#         :param missing_text: The default text to replace a formatter with if the field doesnt exist.
#     """
#     flat_match = flatten_dict(match)
#     flat_match.update(match)
#     dd_match = collections.defaultdict(lambda: missing_text, flat_match)
#     dd_match['_missing_value'] = missing_text
#     while True:
#         try:
#             string = string % dd_match
#             string = string.format(**dd_match)
#             break
#         except KeyError as e:
#             if '{%s}' % str(e).strip("'") not in string:
#                 break
#             string = string.replace('{%s}' % str(e).strip("'"), '{_missing_value}')
# 
#     return string
# 
# Path: elastalert/util.py
# def set_es_key(lookup_dict, term, value):
#     """ Looks up the location that the term maps to and sets it to the given value.
#     :returns: True if the value was set successfully, False otherwise.
#     """
#     value_dict, value_key = _find_es_dict_by_key(lookup_dict, term)
# 
#     if value_dict is not None:
#         value_dict[value_key] = value
#         return True
# 
#     return False
# 
# Path: elastalert/util.py
# def should_scrolling_continue(rule_conf):
#     """
#     Tells about a rule config if it can scroll still or should stop the scrolling.
# 
#     :param: rule_conf as dict
#     :rtype: bool
#     """
#     max_scrolling = rule_conf.get('max_scrolling_count')
#     stop_the_scroll = 0 < max_scrolling <= rule_conf.get('scrolling_cycle')
# 
#     return not stop_the_scroll


# Path: tests/util_test.py
from datetime import datetime
from datetime import timedelta
from dateutil.parser import parse as dt
from elastalert.util import add_raw_postfix
from elastalert.util import format_index
from elastalert.util import lookup_es_key
from elastalert.util import parse_deadline
from elastalert.util import parse_duration
from elastalert.util import replace_dots_in_field_names
from elastalert.util import resolve_string
from elastalert.util import set_es_key
from elastalert.util import should_scrolling_continue
import mock
import pytest

def test_replace_dots_in_field_names(ea):
    actual = {
        'a': {
            'b.c': 'd',
            'e': {
                'f': {
                    'g.h': 0
                }
            }
        },
        'i.j.k': 1,
        'l': {
            'm': 2
        }
    }
    expected = {
        'a': {
            'b_c': 'd',
            'e': {
                'f': {
                    'g_h': 0
                }
            }
        },
        'i_j_k': 1,
        'l': {
            'm': 2
        }
    }
    assert replace_dots_in_field_names(actual) == expected

    assert replace_dots_in_field_names({'a': 0, 1: 2}) == {'a': 0, 1: 2}