#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .base import ApiJob
from common.util import escape_string
from common.util.clients import ClickhouseClient
from common.util.decorators import upload_token_required
from datetime import datetime
from django.http import HttpResponseBadRequest, HttpResponseGone
from json import loads
import re


class JobTrailPush(ApiJob):
    http_method_names = ['post']

    @upload_token_required
    def post(self, request, job):
        """
        :param request: HTTP request
        :param job: job object passed from request
        """

        if job.td:
            user_agent = request.META.get('HTTP_USER_AGENT', '').strip()
            if re.match('^(Overload|Uploader)/.+ YandexTank/.+ Python/.+ OS/.+', user_agent):
                return HttpResponseGone('job has been closed previously')
            else:
                return [{'success': 0, 'msg': 'job has been closed previously'}]

        params = request.body  # POST.get('item')
        if not params:
            return HttpResponseBadRequest('POST data is missing')
        params = loads(params)
        if isinstance(params, dict):
            params = [params]

        self.insert_items(job, params)
        return [{'success': 1}]

    @staticmethod
    def insert_items(job_obj, items):
        # TODO: remake tank datauploader
        # This is stupid, but it's the only way to support singlequotes in tags;
        rt_details_data = ["('%s', %s, '%s', '%s', %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (
            datetime.strftime(job_obj.fd, '%Y-%m-%d'),
            int(job_obj.n),
            escape_string(item['case']),
            int(item['trail']['time']),
            int(item['trail']['connect_time'] * item['trail']['resps'] * 1000),
            int(item['trail']['send_time'] * item['trail']['resps'] * 1000),
            int(item['trail']['latency'] * item['trail']['resps'] * 1000),
            int(item['trail']['receive_time'] * item['trail']['resps'] * 1000),
            int(item['trail']['reqps']),
            int(item['trail']['resps']),
            int(item['trail']['threads']),
            int(item['trail']['input']),
            int(item['trail']['output']),
            0,
        )
                           for item in items
                           ]
        rt_quantiles_data = ["('%s', %s, '%s', '%s', %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (
            datetime.strftime(job_obj.fd, '%Y-%m-%d'),
            int(job_obj.n),
            escape_string(item['case']),
            int(item['trail']['time']),
            float(item['trail']['q50']),
            float(item['trail']['q75']),
            float(item['trail']['q80']),
            float(item['trail']['q85']),
            float(item['trail']['q90']),
            float(item['trail']['q95']),
            float(item['trail']['q98']),
            float(item['trail']['q99']),
            float(item['trail']['q100']),
        )
                             for item in items
                             ]
        net_codes_data = []
        proto_codes_data = []
        rt_histograms_data = []
        for item in items:
            if item['net_codes']:
                net_codes_data.extend([
                                          "('%s', %s, '%s', '%s', %s, %s)" %
                                          (
                                              datetime.strftime(job_obj.fd, '%Y-%m-%d'),
                                              int(job_obj.n),
                                              escape_string(item['case']),
                                              int(item['trail']['time']),
                                              int(net_codes['code']),
                                              int(net_codes['count']),
                                          )
                                          for net_codes in item['net_codes']
                                          ])
            if item['http_codes']:
                proto_codes_data.extend([
                                            "('%s', %s, '%s', '%s', %s, %s)" % (
                                                datetime.strftime(job_obj.fd, '%Y-%m-%d'),
                                                int(job_obj.n),
                                                escape_string(item['case']),
                                                int(item['trail']['time']),
                                                int(proto_codes['code']),
                                                int(proto_codes['count']),
                                            )
                                            for proto_codes in item['http_codes']
                                            ])
            if item['time_intervals']:
                rt_histograms_data.extend([
                                              "('%s', %s, '%s', '%s', %s, %s)" % (
                                                  datetime.strftime(job_obj.fd, '%Y-%m-%d'),
                                                  int(job_obj.n),
                                                  escape_string(item['case']),
                                                  int(item['trail']['time']),
                                                  int(float(time_intervals['to']) * 1000),
                                                  int(time_intervals['count']),
                                              )
                                              for time_intervals in item['time_intervals']
                                              ])

        ch_client = ClickhouseClient()

        if rt_details_data:
            insert_rt_details_query = 'insert into loaddb.rt_microsecond_details_buffer values %s' % ','.join(
                t for t in rt_details_data)
            ch_client.insert(insert_rt_details_query)
        if rt_quantiles_data:
            insert_rt_quantiles_query = 'insert into loaddb.rt_quantiles_buffer values %s' % ','.join(
                t for t in rt_quantiles_data)
            ch_client.insert(insert_rt_quantiles_query)
        if net_codes_data:
            insert_net_codes_query = 'insert into loaddb.net_codes_buffer values %s' % ','.join(
                t for t in net_codes_data)
            ch_client.insert(insert_net_codes_query)
        if proto_codes_data:
            insert_proto_codes_query = 'insert into loaddb.proto_codes_buffer values %s' % ','.join(
                t for t in proto_codes_data)
            ch_client.insert(insert_proto_codes_query)
        if rt_histograms_data:
            insert_rt_histograms_query = 'insert into loaddb.rt_microsecond_histograms_buffer values %s' % ','.join(
                t for t in rt_histograms_data)
            ch_client.insert(insert_rt_histograms_query)
