# Path: py/axonchisel/metrics/io/emfetch/tmrange_time_t.py
# class TimeRange_time_t(timerange.TimeRange):
#     """
#     Extend TimeRange to provide 4 new properties named with _time_t appended.
#     Each contains time_t (in int seconds) version of equivalent properties.
#     Provide patch_format_str support method.
#     May be used internally by EMFetch plugins for string formatting.
#     This object is intended as a read-only decorator and not for updating.
#     New time_t properties are lazily initialized to avoid unnecessary
#     performance penalties when time_t variants are not referenced.
#     """
# 
#     def __init__(self, tmrange):
#         """Init based on a TimeRange."""
#         timerange.TimeRange.__init__(self, 
#             anchor=tmrange.anchor,
#             inc_begin=tmrange.inc_begin,
#             exc_end=tmrange.exc_end,
#         )
# 
# 
#     #
#     # Public Properties
#     #
# 
#     @property
#     def inc_begin_time_t(self):
#         if not hasattr(self, '_inc_begin_time_t'):
#             self._inc_begin_time_t = int(self._dt_to_time_t(self.inc_begin))
#         return self._inc_begin_time_t
# 
#     @property
#     def exc_begin_time_t(self):
#         if not hasattr(self, '_exc_begin_time_t'):
#             self._exc_begin_time_t = int(self._dt_to_time_t(self.exc_begin))
#         return self._exc_begin_time_t
# 
#     @property
#     def inc_end_time_t(self):
#         if not hasattr(self, '_inc_end_time_t'):
#             self._inc_end_time_t = int(self._dt_to_time_t(self.inc_end))
#         return self._inc_end_time_t
# 
#     @property
#     def exc_end_time_t(self):
#         if not hasattr(self, '_exc_end_time_t'):
#             self._exc_end_time_t = int(self._dt_to_time_t(self.exc_end))
#         return self._exc_end_time_t
# 
#     #
#     # Public Static Helpers
#     #
# 
#     @staticmethod
#     def patch_format_str(fmt, varnames):
#         """
#         Given a str.format format str, patch :%s types for _time_t use.
#         
#         The datetime:%s format is intended to request time_t but is not
#         supported natively in Python, and inconsistently on various 
#         platforms.
# 
#         For all 'varname' in varnames list, this method finds references in
#         the format str like:
#             '{varname.bar:%s}'
#         and replaces them with the valid:
#             '{varname.bar_time_t}'
# 
#         It is intended for use with TimeRange_time_t objects.
#         """
#         for varname in varnames:
#             pattern = r'\{' + varname + r'\.(\w+):%s\}'
#             sub = r'{' + varname + '.\\1_time_t}'
#             fmt = re.sub(pattern, sub, fmt)
#         return fmt
#     
# 
#     #
#     # Internal Methods
#     #
#     
#     def _dt_to_time_t(self, dt):
#         """Helper: convert datetime to int time_t"""
#         return int(time.mktime(dt.timetuple()))
# 
# Path: py/axonchisel/metrics/io/emfetch/interface.py
# class EMFetcher(AxPlugin):
#     """
#     EMFetch (Extensible Metrics Fetch) Plugin Interface.
# 
#     MQEngine uses EMFetch plugins to access raw time-indexed metrics data
#     for each data point.
#     Implementations provide access to various data sources by overriding the
#     plugin_fetch() abstract method.
# 
#     See AxPlugin and AxPluginBase for architecture details.
# 
#     Additional Parameters:
# 
#       - mdef : definition of metric to query.
#         (axonchisel.metrics.foundation.metricdef.metricdef.MetricDef)
#     """
# 
#     #
#     # Abstract Methods
#     #
# 
#     # abstract
#     def __init__(self, mdef, extinfo=None):
#         """
#         Initialize around specific MetricDef and optional extinfo dict.
#         """
#         raise NotImplementedError("EMFetcher abstract superclass")
# 
#     # abstract
#     def plugin_fetch(self, tmrange):
#         """
#         EMFetcher plugins must implement this abstract method.
#         Invoked by fetch() after parameters are validated.
#         
#         Returns a single DataPoint.
#             (axonchisel.metrics.foundation.data.point.DataPoint)
# 
#         Parameters:
# 
#           - tmrange : specification of time range to gather data for.
#             (axonchisel.metrics.foundation.chrono.timerange.TimeRange)
#             Also available in TimeRange_time_t format as self._tmrange.
#         """
#         raise NotImplementedError("EMFetcher abstract superclass")


import collections
from axonchisel.metrics.foundation.ax.obj import AxObj
from axonchisel.metrics.foundation.ax.plugin import AxPluginBase
from axonchisel.metrics.foundation.chrono.timerange import TimeRange
from axonchisel.metrics.foundation.metricdef.metricdef import MetricDef
from axonchisel.metrics.foundation.data.point import DataPoint
from .tmrange_time_t import TimeRange_time_t
from .interface import EMFetcher
        dpoint = self.plugin_fetch(tmrange)

        # Validate result DataPoint:
        self._assert_type("result", dpoint, DataPoint)
        return dpoint


    #
    # Public Properties
    #

    @property
    def mdef(self):
        """MetricDef we operate on (get only)."""
        return self._mdef


    #
    # Protected Methods for Subclasses
    #

    def _format_str(self, fmt, what='?', od_defaults = Exception):
        """
        Override from AxPluginBase -
        Format a string using options, extinfo, and extra context (if any).
        Protected wrapper for Python str.format.
        """
        context = dict()
        context['mdef']    = self._mdef
        context['tmrange'] = self._tmrange

# Path: py/axonchisel/metrics/io/emfetch/tmrange_time_t.py
# class TimeRange_time_t(timerange.TimeRange):
#     """
#     Extend TimeRange to provide 4 new properties named with _time_t appended.
#     Each contains time_t (in int seconds) version of equivalent properties.
#     Provide patch_format_str support method.
#     May be used internally by EMFetch plugins for string formatting.
#     This object is intended as a read-only decorator and not for updating.
#     New time_t properties are lazily initialized to avoid unnecessary
#     performance penalties when time_t variants are not referenced.
#     """
# 
#     def __init__(self, tmrange):
#         """Init based on a TimeRange."""
#         timerange.TimeRange.__init__(self, 
#             anchor=tmrange.anchor,
#             inc_begin=tmrange.inc_begin,
#             exc_end=tmrange.exc_end,
#         )
# 
# 
#     #
#     # Public Properties
#     #
# 
#     @property
#     def inc_begin_time_t(self):
#         if not hasattr(self, '_inc_begin_time_t'):
#             self._inc_begin_time_t = int(self._dt_to_time_t(self.inc_begin))
#         return self._inc_begin_time_t
# 
#     @property
#     def exc_begin_time_t(self):
#         if not hasattr(self, '_exc_begin_time_t'):
#             self._exc_begin_time_t = int(self._dt_to_time_t(self.exc_begin))
#         return self._exc_begin_time_t
# 
#     @property
#     def inc_end_time_t(self):
#         if not hasattr(self, '_inc_end_time_t'):
#             self._inc_end_time_t = int(self._dt_to_time_t(self.inc_end))
#         return self._inc_end_time_t
# 
#     @property
#     def exc_end_time_t(self):
#         if not hasattr(self, '_exc_end_time_t'):
#             self._exc_end_time_t = int(self._dt_to_time_t(self.exc_end))
#         return self._exc_end_time_t
# 
#     #
#     # Public Static Helpers
#     #
# 
#     @staticmethod
#     def patch_format_str(fmt, varnames):
#         """
#         Given a str.format format str, patch :%s types for _time_t use.
#         
#         The datetime:%s format is intended to request time_t but is not
#         supported natively in Python, and inconsistently on various 
#         platforms.
# 
#         For all 'varname' in varnames list, this method finds references in
#         the format str like:
#             '{varname.bar:%s}'
#         and replaces them with the valid:
#             '{varname.bar_time_t}'
# 
#         It is intended for use with TimeRange_time_t objects.
#         """
#         for varname in varnames:
#             pattern = r'\{' + varname + r'\.(\w+):%s\}'
#             sub = r'{' + varname + '.\\1_time_t}'
#             fmt = re.sub(pattern, sub, fmt)
#         return fmt
#     
# 
#     #
#     # Internal Methods
#     #
#     
#     def _dt_to_time_t(self, dt):
#         """Helper: convert datetime to int time_t"""
#         return int(time.mktime(dt.timetuple()))
# 
# Path: py/axonchisel/metrics/io/emfetch/interface.py
# class EMFetcher(AxPlugin):
#     """
#     EMFetch (Extensible Metrics Fetch) Plugin Interface.
# 
#     MQEngine uses EMFetch plugins to access raw time-indexed metrics data
#     for each data point.
#     Implementations provide access to various data sources by overriding the
#     plugin_fetch() abstract method.
# 
#     See AxPlugin and AxPluginBase for architecture details.
# 
#     Additional Parameters:
# 
#       - mdef : definition of metric to query.
#         (axonchisel.metrics.foundation.metricdef.metricdef.MetricDef)
#     """
# 
#     #
#     # Abstract Methods
#     #
# 
#     # abstract
#     def __init__(self, mdef, extinfo=None):
#         """
#         Initialize around specific MetricDef and optional extinfo dict.
#         """
#         raise NotImplementedError("EMFetcher abstract superclass")
# 
#     # abstract
#     def plugin_fetch(self, tmrange):
#         """
#         EMFetcher plugins must implement this abstract method.
#         Invoked by fetch() after parameters are validated.
#         
#         Returns a single DataPoint.
#             (axonchisel.metrics.foundation.data.point.DataPoint)
# 
#         Parameters:
# 
#           - tmrange : specification of time range to gather data for.
#             (axonchisel.metrics.foundation.chrono.timerange.TimeRange)
#             Also available in TimeRange_time_t format as self._tmrange.
#         """
#         raise NotImplementedError("EMFetcher abstract superclass")


# Path: py/axonchisel/metrics/io/emfetch/base.py
import collections
from axonchisel.metrics.foundation.ax.obj import AxObj
from axonchisel.metrics.foundation.ax.plugin import AxPluginBase
from axonchisel.metrics.foundation.chrono.timerange import TimeRange
from axonchisel.metrics.foundation.metricdef.metricdef import MetricDef
from axonchisel.metrics.foundation.data.point import DataPoint
from .tmrange_time_t import TimeRange_time_t
from .interface import EMFetcher

        dpoint = self.plugin_fetch(tmrange)

        # Validate result DataPoint:
        self._assert_type("result", dpoint, DataPoint)
        return dpoint


    #
    # Public Properties
    #

    @property
    def mdef(self):
        """MetricDef we operate on (get only)."""
        return self._mdef


    #
    # Protected Methods for Subclasses
    #

    def _format_str(self, fmt, what='?', od_defaults = Exception):
        """
        Override from AxPluginBase -
        Format a string using options, extinfo, and extra context (if any).
        Protected wrapper for Python str.format.
        """
        context = dict()
        context['mdef']    = self._mdef
        context['tmrange'] = self._tmrange

        fmt = TimeRange_time_t.patch_format_str(fmt, ('tmrange',))