# Path: protector/influxdb/daterange.py
# class DateRange(object):
#     """
#     A thin abstraction layer for date ranges
#     """
# 
#     def __init__(self, start, end):
#         self.start = start
#         self.end = end
# 
#     def timespan(self):
#         return self.end - self.start
# 
#     def timespan_seconds(self):
#         t = self.timespan()
#         # A duration can never be negative
#         return max(0, t.total_seconds())
# 
#     def __str__(self):
#         return "Start: {}, End: {}, (Time span: {})".format(self.start, self.end, self.timespan())
# 
#     def __repr__(self):
#         return self.__str__()
# 
#     def __eq__(self, other):
#         if isinstance(other, self.__class__):
#             return (self.start == other.start) and (self.end == other.end)
#         else:
#             return False
# 
#     def __ne__(self, other):
#         return not self.__eq__(other)
# 
# Path: protector/influxdb/time_expression.py
# class TimeExpression(object):
#     # Smallest possible system date.
#     # This is required for the calculation of the max duration between datetime objects.
#     # We use the release day of InfluxDB 0.8 as the epoch
#     # because it is the first official version supported by this tool.
#     INFLUXDB_EPOCH = datetime.strptime('2014-08-22', "%Y-%m-%d")
# 
#     # Full names of all supported relative time units.
#     # Useful for conversions of the internal InfluxDB format to the Python timedelta format.
#     UNIT_NAMES = {
#         'u': 'microseconds',
#         's': 'seconds',
#         'm': 'minutes',
#         'h': 'hours',
#         'd': 'days',
#         'w': 'weeks'
#     }
# 
#     # Conversions of all InfluxDB relative time units to seconds.
#     # Useful for datapoint calculations.
#     UNIT_CONVERSION = {'u': 0.001, 's': 1, 'm': 60, 'h': 3600, 'd': 86400, 'w': 604800}
# 
# Path: protector/parser/subparsers/duration.py
# class DurationParser(object):
#     def __init__(self):
#         pass
# 
#     def parse(self, time_ranges):
#         if not time_ranges:
#             # Get the biggest duration if nothing else is specified
#             return DateRange(TimeExpression.INFLUXDB_EPOCH, datetime.now())
# 
#         # Calculate overlap of all time ranges.
#         # Start with the first one
#         overlap = time_ranges[0]
#         for time_range in time_ranges:
#             overlap = self.calculate_overlap(overlap, time_range)
# 
#         # Return the overlap as a date range and as the number of seconds
#         return overlap
# 
#     @staticmethod
#     def calculate_overlap(range1, range2):
#         latest_start = max(range1.start, range2.start)
#         earliest_end = min(range1.end, range2.end)
#         overlap = DateRange(latest_start, earliest_end)
#         return overlap


import unittest
from datetime import timedelta, datetime
from freezegun import freeze_time
from protector.influxdb.daterange import DateRange
from protector.influxdb.time_expression import TimeExpression
from protector.parser.subparsers.duration import DurationParser



@freeze_time("2015-11-04")
class TestParseDuration(unittest.TestCase):
    def test_durations(self):
        """
        Test simple time durations (i.e. only one time condition in the where clause)
        """
        now = datetime.now()
        epoch = TimeExpression.INFLUXDB_EPOCH
        d = DurationParser()
        self.assertEqual(d.parse([DateRange(now - timedelta(hours=2), now)]).timespan_seconds(), 2 * 60 * 60)
        self.assertEqual(d.parse([DateRange(now - timedelta(seconds=12), now)]).timespan_seconds(), 12)
        self.assertEqual(d.parse([DateRange(now - timedelta(weeks=23), now)]).timespan_seconds(), 23 * 7 * 24 * 60 * 60)
        # Times in the future will result in a duration of 0 seconds
        self.assertEqual(d.parse([DateRange(now + timedelta(microseconds=100), now)]).timespan_seconds(), 0)
        self.assertEqual(d.parse([DateRange(now - timedelta(microseconds=100), now - timedelta(microseconds=100))]).timespan_seconds(), 0)
        self.assertEqual(d.parse([DateRange(epoch, datetime(2014, 8, 23))]).timespan_seconds(), 24 * 60 * 60)
        self.assertEqual(d.parse([DateRange(datetime(2013, 11, 4, 9, 30, 0, 232000), now)]).timespan_seconds(), 63037799.768)
        self.assertEqual(d.parse([DateRange(datetime(2013, 8, 10), datetime(2013, 8, 20)),

# Path: protector/influxdb/daterange.py
# class DateRange(object):
#     """
#     A thin abstraction layer for date ranges
#     """
# 
#     def __init__(self, start, end):
#         self.start = start
#         self.end = end
# 
#     def timespan(self):
#         return self.end - self.start
# 
#     def timespan_seconds(self):
#         t = self.timespan()
#         # A duration can never be negative
#         return max(0, t.total_seconds())
# 
#     def __str__(self):
#         return "Start: {}, End: {}, (Time span: {})".format(self.start, self.end, self.timespan())
# 
#     def __repr__(self):
#         return self.__str__()
# 
#     def __eq__(self, other):
#         if isinstance(other, self.__class__):
#             return (self.start == other.start) and (self.end == other.end)
#         else:
#             return False
# 
#     def __ne__(self, other):
#         return not self.__eq__(other)
# 
# Path: protector/influxdb/time_expression.py
# class TimeExpression(object):
#     # Smallest possible system date.
#     # This is required for the calculation of the max duration between datetime objects.
#     # We use the release day of InfluxDB 0.8 as the epoch
#     # because it is the first official version supported by this tool.
#     INFLUXDB_EPOCH = datetime.strptime('2014-08-22', "%Y-%m-%d")
# 
#     # Full names of all supported relative time units.
#     # Useful for conversions of the internal InfluxDB format to the Python timedelta format.
#     UNIT_NAMES = {
#         'u': 'microseconds',
#         's': 'seconds',
#         'm': 'minutes',
#         'h': 'hours',
#         'd': 'days',
#         'w': 'weeks'
#     }
# 
#     # Conversions of all InfluxDB relative time units to seconds.
#     # Useful for datapoint calculations.
#     UNIT_CONVERSION = {'u': 0.001, 's': 1, 'm': 60, 'h': 3600, 'd': 86400, 'w': 604800}
# 
# Path: protector/parser/subparsers/duration.py
# class DurationParser(object):
#     def __init__(self):
#         pass
# 
#     def parse(self, time_ranges):
#         if not time_ranges:
#             # Get the biggest duration if nothing else is specified
#             return DateRange(TimeExpression.INFLUXDB_EPOCH, datetime.now())
# 
#         # Calculate overlap of all time ranges.
#         # Start with the first one
#         overlap = time_ranges[0]
#         for time_range in time_ranges:
#             overlap = self.calculate_overlap(overlap, time_range)
# 
#         # Return the overlap as a date range and as the number of seconds
#         return overlap
# 
#     @staticmethod
#     def calculate_overlap(range1, range2):
#         latest_start = max(range1.start, range2.start)
#         earliest_end = min(range1.end, range2.end)
#         overlap = DateRange(latest_start, earliest_end)
#         return overlap


# Path: protector/tests/parser_test/subparser_test/test_duration_parser.py
import unittest
from datetime import timedelta, datetime
from freezegun import freeze_time
from protector.influxdb.daterange import DateRange
from protector.influxdb.time_expression import TimeExpression
from protector.parser.subparsers.duration import DurationParser




@freeze_time("2015-11-04")
class TestParseDuration(unittest.TestCase):
    def test_durations(self):
        """
        Test simple time durations (i.e. only one time condition in the where clause)
        """
        now = datetime.now()
        epoch = TimeExpression.INFLUXDB_EPOCH
        d = DurationParser()
        self.assertEqual(d.parse([DateRange(now - timedelta(hours=2), now)]).timespan_seconds(), 2 * 60 * 60)
        self.assertEqual(d.parse([DateRange(now - timedelta(seconds=12), now)]).timespan_seconds(), 12)
        self.assertEqual(d.parse([DateRange(now - timedelta(weeks=23), now)]).timespan_seconds(), 23 * 7 * 24 * 60 * 60)
        # Times in the future will result in a duration of 0 seconds
        self.assertEqual(d.parse([DateRange(now + timedelta(microseconds=100), now)]).timespan_seconds(), 0)
        self.assertEqual(d.parse([DateRange(now - timedelta(microseconds=100), now - timedelta(microseconds=100))]).timespan_seconds(), 0)
        self.assertEqual(d.parse([DateRange(epoch, datetime(2014, 8, 23))]).timespan_seconds(), 24 * 60 * 60)
        self.assertEqual(d.parse([DateRange(datetime(2013, 11, 4, 9, 30, 0, 232000), now)]).timespan_seconds(), 63037799.768)
        self.assertEqual(d.parse([DateRange(datetime(2013, 8, 10), datetime(2013, 8, 20)),

                                  DateRange(datetime(2013, 8, 12), datetime(2013, 8, 18))]).timespan_seconds(), 6 * 24 * 60 * 60)