# coding: utf-8

from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

from six import iteritems
from collections import defaultdict
from cached_property import cached_property

from saas.library.python.yasm.signal import YasmSignal
from saas.library.python.yasm.common import get_interval_begin_end

from infra.yasm.yasmapi import GolovanRequest, RtGolovanRequest


class YasmSignalGroup(object):
    def __init__(self, *signals):
        self._signals = set()
        for signal in signals:
            if isinstance(signal, YasmSignal):
                self._signals.add(signal)
            else:
                self._signals.add(YasmSignal.from_str(signal))

    @cached_property
    def tags_signals(self):
        tags_signals_mapping = {}
        for _signal in self._signals:
            if _signal.tags_str not in tags_signals_mapping:
                tags_signals_mapping[_signal.tags_str] = set()
            tags_signals_mapping[_signal.tags_str].add(_signal.signal)
        return {k: list(v) for k, v in iteritems(tags_signals_mapping)}

    def iterate_rt(self, host='ASEARCH'):
        for p in RtGolovanRequest({host: self.tags_signals}):
            yield p.ts, p.values[host]

    def iterate_interval(self, period, interval_begin, interval_end, host='ASEARCH'):
        period, interval_begin, interval_end = get_interval_begin_end(period, interval_begin, interval_end)
        for ts, values in GolovanRequest(host, period.value, interval_begin, interval_end,
                                         [str(signal) for signal in self._signals]):
            signal_value_map = {YasmSignal.from_str(signal_str): value for signal_str, value in iteritems(values)}
            values = defaultdict(dict)
            for signal, value in iteritems(signal_value_map):
                values[signal.tags_str][signal.signal] = value
            yield ts, values

    def __repr__(self):
        return 'YasmSignalGroup([{}])'.format(
            ','.join([s.__repr__() for s in sorted(self._signals)])
        )

    def __eq__(self, other):
        if isinstance(other, YasmSignalGroup):
            return self._signals == other._signals
        else:
            return NotImplemented
