# -*- coding: utf-8 -*-
import re
import yt.wrapper as yt
from datacloud.dev_utils.logging.logger import get_basic_logger
from datacloud.dev_utils.yt.yt_utils import get_yt_client
from datacloud.dev_utils.solomon.solomon_utils import get_schema, post_schema_to_solomon
from collections import Counter
from datacloud.dev_utils.time.patterns import RE_DAILY_LOG_FORMAT, RE_5MIN_LOG_FORMAT
from datacloud.dev_utils.status_db.task import Status
from datacloud.config.yt import YT_PROXY


logger = get_basic_logger(__name__)
ROUTER_LOG_STREAM_DIR = '//home/x-products/production/services/logs/router/stream/5min'
ROUTER_LOG_HISTORY_DIR = '//home/x-products/production/services/logs/router/history'


class LogUploaderToSolomon(object):
    def __init__(self, project, cluster, service, yt_client):
        self.schema = get_schema(project, cluster, service)
        self.schema['sensors'] = []
        self.pack_to_send = Counter()
        self.labels_keys = None
        self.prev_ts = None
        self.counter = 0
        self.yt_client = yt_client

    def add_rec_to_pack(self, rec):
        labels, ts = self.extract_labels_ts_from_rec(rec)

        self.labels_keys = labels.keys()
        if ts != self.prev_ts and self.counter > 10000:
            self.counter = 0
            self.send_to_solomon()

        self.pack_to_send[(tuple(labels.values()), ts)] += 1
        self.counter += 1
        self.prev_ts = ts

    def pack_to_sensors(self):
        for key, val in self.pack_to_send.items():
            self.schema['sensors'].append({
                'labels': dict((key, val) for (key, val) in zip(self.labels_keys, key[0])),
                'ts': key[1],
                'value': val
            })
        self.pack_to_send = Counter()

    def send_to_solomon(self):
        self.pack_to_sensors()
        post_schema_to_solomon(self.schema, wait=0.0000001, repeats=10)
        self.schema['sensors'] = []

    def send_table_to_solomon(self, table):
        row_count = self.yt_client.get_attribute(table, 'row_count')
        counter = 0
        for rec in self.yt_client.read_table(table):
            if counter % 10000 == 0:
                logger.info('Loaded {}/{}'.format(counter, row_count))
            self.add_rec_to_pack(rec)
            counter += 1
        self.send_to_solomon()

    def __str__(self):
        return str(self.labels_keys)

    def extract_labels_ts_from_rec(self, rec):
        raise NotImplementedError('Should be defined for children')


class RouterLogUploaderToSolomon(LogUploaderToSolomon):
    def __init__(self, *args, **kwargs):
        super(RouterLogUploaderToSolomon, self).__init__(*args, **kwargs)

    def extract_labels_ts_from_rec(self, rec):
        labels = {
            'qloud_instance': rec['qloud_instance'],
            'qloud_environment': rec['qloud_environment'],
            'qloud_application': rec['qloud_application'],
            'status': rec['status'],
            'partner_id': rec['request'].split('/')[-2]
        }
        ts = int(float(rec['ts']))
        return labels, ts


def run_upload_router_logs_to_solomon(task):
    table = task.data['table_path']
    yt_client = get_yt_client(YT_PROXY)
    logger.info(' Start upload table: {}'.format(table))
    if yt_client.exists(table):
        loader = RouterLogUploaderToSolomon('datacloud', 'score', 'router', yt_client)
        loader.send_table_to_solomon(table)
        new_tasks = [task.make_done()]
    else:
        logger.warn('There is no input table on YT {}'.format(table))
        new_tasks = [task.make_done(new_status=Status.SKIPPED)]
    return new_tasks


def detect_router_logs_to_solomon(date_time, days=None):
    yt_client = get_yt_client(YT_PROXY)
    for table in yt_client.list(ROUTER_LOG_STREAM_DIR, absolute=True):
        date = table.split('/')[-1]
        if re.match(RE_5MIN_LOG_FORMAT, date):
            yield table, {'table_path': table}
    for table in yt_client.list(ROUTER_LOG_HISTORY_DIR, absolute=True):
        date = table.split('/')[-1]
        if re.match(RE_DAILY_LOG_FORMAT, date):
            yield table, {'table_path': table}


if __name__ == '__main__':
    yt.config.set_proxy(YT_PROXY)
    yt_client = get_yt_client(YT_PROXY)
    a = RouterLogUploaderToSolomon('datacloud', 'score', 'router', yt_client)
    print(a)
    # router_table = '//home/x-products/production/services/logs/router/history/2018-12-15'
    # a.send_table_to_solomon(router_table)
    for table in yt_client.list('//home/x-products/production/services/logs/router/stream/5min', absolute=True):
        a.send_table_to_solomon(table)
    # a.send_table_to_solomon(router_table)

    # router_table = '//home/x-products/production/services/logs/router/stream/5min/2018-12-13T15:45:00'
    # recs = yt_client.read_table(router_table)
    # rec = next(recs)
    # for i in range(100):
    #     rec = next(recs)
    #     labels = {'qloud_instance': rec['qloud_instance'], 'status': rec['status'], 'partner_id': rec['request'].split('/')[-2]}
    #     value = 1
    #     ts = float(rec['ts'])
    #     post_router_results_to_solomon(value, labels, ts)
