# -*- coding: utf-8 -*-
from io import StringIO
import logging
import pandas as pd
from yt import wrapper as yt
from yql.api.v1.client import YqlClient
from yql.client.operation import YqlOperationType, YqlOperationShareIdRequest
from robot import SECRET
from robot.errs import YQLError


logger = logging.getLogger(__name__)


class YQLWorker(object):
    def __init__(self, parent=None, yql_query=None, result_names=None, operation_type=YqlOperationType.SQLv1):
        super(YQLWorker, self).__init__()
        logger.debug('%s: init YQLWorker', parent.issue.key)

        self.parent = parent
        self.issue = parent.issue
        self.yql_query = yql_query
        self.operation_type = operation_type
        self.result_names = result_names
        self.result, self.dfs = None, {}

        logger.debug('%s: YQLWorker initialized', self.issue.key)

    def run(self):
        logger.debug('%s: run YQLWorker', self.issue.key)

        yql_client = YqlClient(token=SECRET['token'])
        request = yql_client.query(self.yql_query, syntax_version=1)
        request.type = self.operation_type
        request.run()

        self.result = request.get_results()
        tables = []
        for table in self.result:
            table.fetch_full_data()
            tables.append(table)

        if not self.result.is_success:
            message = '%s: result isn\'t success!' % self.issue.key
            logger.error(message)
            if not self.parent.test_mode:
                self.issue.comments.create(text=u'Запрос завершился ошибкой. ((%s Ссылка на расчет в YQL)).\n'
                                                u'<{Подробнее:'
                                                u'\n%%%%\n%s\n%%%%'
                                                u'}>' % (self.get_public_url(),
                                                         u'\n'.join([err.format_issue() for err in self.result.errors])
                                                         ),
                                           summonees=['orlovgb', 'zedlaa'])

            raise YQLError(message)

        logger.debug('%s: request completed', self.issue.key)

        for key, table in zip(self.result_names, tables):
            df = table.full_dataframe
            df['Client'] = df.Client.apply(lambda cell:
                                           cell.decode('utf-8') if not isinstance(cell, (int, unicode)) else cell)
            self.dfs[key] = df

    def get_public_url(self):
        share_req = YqlOperationShareIdRequest(self.result.operation_id)
        share_req.run()
        return 'https://yql.yandex-team.ru/Operations/{}'.format(share_req.json)


def read_table(table_path, columns):
    yt_client = yt.YtClient(token=SECRET['token'], proxy='hahn')
    table = yt_client.read_table(
        table_path,
        raw=True,
        format=yt.SchemafulDsvFormat(columns=columns,
                                     attributes={'missing_value_mode': 'print_sentinel',
                                                 'missing_value_sentinel': 'null'})
    )
    df = pd.read_table(
        StringIO('\n'.join(table).decode('utf-8')),
        names=columns,
        encoding='utf-8', decimal='.', na_values=('Null', 'null', 'NULL'), na_filter=True,
        quoting=3, low_memory=True, engine='c'
    )

    return df
