# Path: py/axonchisel/metrics/run/mqengine/mqestate.py
# class MQEState(AxObj):
#     """
#     MQEngine state encapsulation.
#     Lifecycle: Should be reset() before each query.
#     """
# 
#     def __init__(self, mqe):
#         """Init with back pointer to parent MQEngine."""
#         # Set valid default state:
#         self._mqe = None
#         self.reset()
# 
#         # Apply initial values from args:
#         self.mqe = mqe
# 
# 
#     #
#     # Public Methods
#     #
# 
#     def reset(self, query=None):
#         """Reset state, to allow new queries."""
#         self.mdseries  = MultiDataSeries()  # current results accumulation
#         self._query    = None
#         self._tmfrspec = None
#         if query:
#             self.query    = query              # current Query obj
# 
#     def pin_tmfrspec(self):
#         """
#         Saves pinned (fixed reframe_dt) copy of Query's FrameSpec.
#         Ensures all step sequences run over same time frame even if some
#         take a long time to execute (because "now" doesn't change).
#         """
#         tmfrspec = copy.deepcopy(self.query.qtimeframe.tmfrspec)
#         if tmfrspec.reframe_dt is None:
#             tmfrspec.reframe_dt = datetime.now()
#         self.tmfrspec = tmfrspec
# 
# 
#     #
#     # Public Properties
#     #
# 
#     @property
#     def query(self):
#         """Query currently working on."""
#         return self._query
#     @query.setter
#     def query(self, val):
#         self._assert_type("query", val, Query)
#         self._query = val
# 
#     @property
#     def tmfrspec(self):
#         """Pinned FrameSpec (adjusted from Query)."""
#         return self._tmfrspec
#     @tmfrspec.setter
#     def tmfrspec(self, val):
#         self._assert_type("tmfrspec", val, FrameSpec)
#         self._tmfrspec = val
# 
#     @property
#     def mdseries(self):
#         """MultiDataSeries accumulating data into."""
#         return self._mdseries
#     @mdseries.setter
#     def mdseries(self, val):
#         self._assert_type("mdseries", val, MultiDataSeries)
#         self._mdseries = val
# 
# 
#     #
#     # Internal Methods
#     #
# 
#     def __unicode__(self):
#         return (u"MQEState()"
#         ).format(self=self)


import collections
import time
import axonchisel.metrics.foundation.ax.plugin as axplugin
import axonchisel.metrics.io.emfetch.base
import logging
from axonchisel.metrics.foundation.ax.obj import AxObj
from axonchisel.metrics.foundation.chrono.stepper import Stepper
from axonchisel.metrics.foundation.metricdef.metset import MetSet
from axonchisel.metrics.foundation.data.point import DataPoint
from axonchisel.metrics.foundation.data.series import DataSeries 
from axonchisel.metrics.foundation.data.multi import MultiDataSeries 
from axonchisel.metrics.foundation.query.query import Query
from .mqestate import MQEState


# ----------------------------------------------------------------------------


class MQEngine(AxObj):
    """
    Metrics Query Engine - executes queries, yielding data.

    MQEngine has access to a MetSet of metrics.
    It can execute a Query to generate MultiDataSeries result.

    Lifecycle: An MQEngine instance can execute as many queries
    as desired, but only one at a time.
    """

    def __init__(self,
        metset,
        emfetch_extinfo = None  #  dict  (map pluginid:dict)
    ):
        # Set valid default state:
        self._metset          = MetSet()
        self._emfetch_extinfo = dict()

        # Apply initial values from kwargs:
        self.metset           = metset
        if emfetch_extinfo is not None:
            self.emfetch_extinfo  = emfetch_extinfo

        # Prep internal state:

# Path: py/axonchisel/metrics/run/mqengine/mqestate.py
# class MQEState(AxObj):
#     """
#     MQEngine state encapsulation.
#     Lifecycle: Should be reset() before each query.
#     """
# 
#     def __init__(self, mqe):
#         """Init with back pointer to parent MQEngine."""
#         # Set valid default state:
#         self._mqe = None
#         self.reset()
# 
#         # Apply initial values from args:
#         self.mqe = mqe
# 
# 
#     #
#     # Public Methods
#     #
# 
#     def reset(self, query=None):
#         """Reset state, to allow new queries."""
#         self.mdseries  = MultiDataSeries()  # current results accumulation
#         self._query    = None
#         self._tmfrspec = None
#         if query:
#             self.query    = query              # current Query obj
# 
#     def pin_tmfrspec(self):
#         """
#         Saves pinned (fixed reframe_dt) copy of Query's FrameSpec.
#         Ensures all step sequences run over same time frame even if some
#         take a long time to execute (because "now" doesn't change).
#         """
#         tmfrspec = copy.deepcopy(self.query.qtimeframe.tmfrspec)
#         if tmfrspec.reframe_dt is None:
#             tmfrspec.reframe_dt = datetime.now()
#         self.tmfrspec = tmfrspec
# 
# 
#     #
#     # Public Properties
#     #
# 
#     @property
#     def query(self):
#         """Query currently working on."""
#         return self._query
#     @query.setter
#     def query(self, val):
#         self._assert_type("query", val, Query)
#         self._query = val
# 
#     @property
#     def tmfrspec(self):
#         """Pinned FrameSpec (adjusted from Query)."""
#         return self._tmfrspec
#     @tmfrspec.setter
#     def tmfrspec(self, val):
#         self._assert_type("tmfrspec", val, FrameSpec)
#         self._tmfrspec = val
# 
#     @property
#     def mdseries(self):
#         """MultiDataSeries accumulating data into."""
#         return self._mdseries
#     @mdseries.setter
#     def mdseries(self, val):
#         self._assert_type("mdseries", val, MultiDataSeries)
#         self._mdseries = val
# 
# 
#     #
#     # Internal Methods
#     #
# 
#     def __unicode__(self):
#         return (u"MQEState()"
#         ).format(self=self)


# Path: py/axonchisel/metrics/run/mqengine/mqengine.py
import collections
import time
import axonchisel.metrics.foundation.ax.plugin as axplugin
import axonchisel.metrics.io.emfetch.base
import logging
from axonchisel.metrics.foundation.ax.obj import AxObj
from axonchisel.metrics.foundation.chrono.stepper import Stepper
from axonchisel.metrics.foundation.metricdef.metset import MetSet
from axonchisel.metrics.foundation.data.point import DataPoint
from axonchisel.metrics.foundation.data.series import DataSeries 
from axonchisel.metrics.foundation.data.multi import MultiDataSeries 
from axonchisel.metrics.foundation.query.query import Query
from .mqestate import MQEState



# ----------------------------------------------------------------------------


class MQEngine(AxObj):
    """
    Metrics Query Engine - executes queries, yielding data.

    MQEngine has access to a MetSet of metrics.
    It can execute a Query to generate MultiDataSeries result.

    Lifecycle: An MQEngine instance can execute as many queries
    as desired, but only one at a time.
    """

    def __init__(self,
        metset,
        emfetch_extinfo = None  #  dict  (map pluginid:dict)
    ):
        # Set valid default state:
        self._metset          = MetSet()
        self._emfetch_extinfo = dict()

        # Apply initial values from kwargs:
        self.metset           = metset
        if emfetch_extinfo is not None:
            self.emfetch_extinfo  = emfetch_extinfo

        # Prep internal state:

        self._state = MQEState(self)