# -*- coding: utf-8 -*-
"""
Модуль, сохраняющий данные котировок в БД.
"""

from stocks3.core.config import Configurable
from stocks3.core import factories
from stocks3.core.stock import AbstractPrice
from stocks3.core.exception import S3Exception, throw_only

__author__ = "Zasimov Alexey"
__email__ = "zasimov-a@yandex-team.ru"


class S3SaverError(S3Exception):
    STAGE = "saver"


class Saver(Configurable):
    """
    Модуль, сохраняющий данные о котировках.
    """

    def __init__(self, tree, node, source, **kwargs):
        self.source = source
        self.checkers = []
        self.disable_checks_list = []
        Configurable.__init__(self, tree, node, **kwargs)

    def set_disable_checks_list(self, disable_checks_list):
        """
        Вызывается из L{Source.set_disable_checks_list}.
        """
        self.disable_checks_list = disable_checks_list

    def makeConfig(self):
        Configurable.makeConfig(self)
        self.checkers = self.createObjects(factories.checkers, "checkers/checker", self.source)

    def save(self, price):
        """
        Вызывается внешним модулем (скорее всего из Source).

        @type price: L{AbstractPrice}.
        @param price: Данные для сохранения.
        """
        assert isinstance(price, AbstractPrice), "Expected Price, but received %s" % price.__class__
        pass

    def _need_check(self, price):
        """
        Возвращает True, если котировка должна быть проверена и False, если
        проверки нужно пропустить.
        """
        return price.quote.quote_id not in self.disable_checks_list

    @throw_only(S3SaverError)
    def run_save(self, price, test=False):
        # Проверяем значения по чекерам
        if self._need_check(price):
            for checker in self.checkers:
                if not checker.run_check(price):
                    self._info(
                        "skipped: %s: %s because of %s" % (self.source.sourceId, price.show(), checker.__class__))
                    return None
        else:
            # Пропускаем проверку для этой котировки (так как эта котировка
            # числится в self.disable_checks_list).
            pass

        if test:
            return self._need_check(price)
        self._info("saved: %s: %s" % (self.source.sourceId, price.show()))
        return self.save(price)

    def flush(self):
        pass

    def clean(self):
        pass

    @throw_only(S3SaverError)
    def run_flush(self):
        return self.flush()
