#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
from datetime import datetime

from .clients import ClickhouseClient
from common.models import JobTrail


def set_job_trail(job, recompute=0):
    success = False
    error = ''
    try:
        job_t = job.jobtrail_set.all()  # JobTrail.objects.filter(up=job)
        if job_t.count() > 0:
            if recompute:
                job_t.delete()  # !!!
            else:
                error = 'Job already analysed.'
                return [{'success': int(success), 'error': error}]

        ch_client = ClickhouseClient()

        extremes = ch_client.select('''
            select min(reqps), max(reqps), min(time), max(time)
            from loaddb.rt_microsecond_details_buffer
            where job_id = {job}
            and job_date=toDate({job_date})
            and tag=''
            ''', query_params=job.basic_query_params)
        min_rps, max_rps, trail_start, trail_stop = extremes[0] if extremes else (0, 0, datetime.now(), datetime.now())

        http = ch_client.select('''
            select distinct toString(code)
            from loaddb.proto_codes_buffer
            where job_id = {job}
            and job_date=toDate({job_date})
            and tag=''
            and code != 200
            ''', query_params=job.basic_query_params)
        http = ','.join(http[0]) if http else '200'

        net = int(any(ch_client.select('''
            select toInt32(count())
            from loaddb.net_codes_buffer
            where job_id = {job}
            and job_date=toDate({job_date})
            and tag=''
            and code != 0
            ''', query_params=job.basic_query_params)))
        avg_resps = ch_client.select('''
            select round(toFloat64(avg(resps)), 3)
            from loaddb.rt_microsecond_details_buffer
            where job_id = {job}
            and job_date=toDate({job_date})
            and tag=''
            ''', query_params=job.basic_query_params)
        avg_resps = avg_resps[0][0] if avg_resps and avg_resps[0] else 0
        avg_expect = ch_client.select('''
            select round(toFloat64(sum(connect_time_sum + send_time_sum + latency_sum + receive_time_sum)/sum(resps))/1000, 3)
            from loaddb.rt_microsecond_details_buffer
            where job_id = {job}
            and job_date=toDate({job_date})
            and tag=''
        ''', query_params=job.basic_query_params)[0][0]
        avg_connect_time = ch_client.select('''
            select round(toFloat64(sum(connect_time_sum)/sum(resps))/1000, 3)
            from loaddb.rt_microsecond_details_buffer
            where job_id = {job}
            and job_date=toDate({job_date})
            and tag=''
        ''', query_params=job.basic_query_params)[0][0]
        avg_send_time = ch_client.select('''
            select round(toFloat64(sum(send_time_sum)/sum(resps))/1000, 3)
            from loaddb.rt_microsecond_details_buffer
            where job_id={job}
            and tag=''
        ''', query_params=job.basic_query_params)[0][0]
        avg_latency = ch_client.select('''
            select round(toFloat64(sum(latency_sum)/sum(resps))/1000, 3)
            from loaddb.rt_microsecond_details_buffer
            where job_id = {job}
            and job_date=toDate({job_date})
            and tag=''
        ''', query_params=job.basic_query_params)[0][0]
        avg_receive_time = ch_client.select('''
            select round(toFloat64(sum(receive_time_sum)/sum(resps))/1000, 3)
            from loaddb.rt_microsecond_details_buffer
            where job_id = {job}
            and job_date=toDate({job_date})
            and tag=''
        ''', query_params=job.basic_query_params)[0][0]

        job_t = JobTrail(up=job,
                         min_rps=min_rps,
                         max_rps=max_rps,
                         http=http,
                         net=net,
                         avg_resps=avg_resps,
                         trail_start=trail_start,
                         trail_stop=trail_stop,
                         avg_expect=avg_expect,
                         avg_connect_time=avg_connect_time,
                         avg_send_time=avg_send_time,
                         avg_latency=avg_latency,
                         avg_receive_time=avg_receive_time
                         )

        quantiles = 'q50', 'q75', 'q80', 'q85', 'q90', 'q95', 'q98', 'q99'
        quantiles_values = ch_client.select('''
            select quantilesExactWeighted(0.50, 0.75, 0.80, 0.85, 0.90, 0.95, 0.98, 0.99)(bin, cnt)
            from loaddb.rt_microsecond_histograms_buffer
            where job_id = {job}
            and job_date=toDate({job_date})
            and tag=''
            ''', query_params=job.basic_query_params)
        quantiles_values = [float(q)/1000 for q in quantiles_values[0][0]] if quantiles_values else [0] * len(quantiles)
        for q in quantiles:
            setattr(job_t, q, quantiles_values[quantiles.index(q)])
        job_t.save()
        success = True
    except Exception as exc:
        logging.exception('')
        error = exc
    return [{'success': int(success), 'error': error}]
